Shell 编程问题,怎么保证脚本的执行环境在没污染的环境下? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
sunjourney
V2EX    程序员

Shell 编程问题,怎么保证脚本的执行环境在没污染的环境下?

  •  
  •   sunjourney 2017-04-19 11:06:14 +08:00 3467 次点击
    这是一个创建于 3148 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 shell 里给自己写的程序加了 alias wc=count ,但 count 的用法和 wc 不同 ,另外一个以前写的脚本用到了 wc, 现在执行会报错,它错误地使用了 count 。怎么使使这个以前的脚本一定用的是 wc 而不是我现在的 count 。其实我 tr 也被 alias 到了 tr=translate,也有使用的问题

    这段脚本大概是这样:

    res=$(echo $0 | grep '^pass' | wc -l | tr -d ' ') 

    感觉和上下文有关吧?怎么让以前这个程序处在没有加 alias 的环境下呢?

    第 1 条附言    2017-04-19 12:24:53 +08:00
    有一点很重要,补充一下,用了 wc, tr 的脚本写在 zsh 的 主题文件下,都是通过 source 执行,因此会读到被 alias 到的程序。
    25 条回复    2017-04-19 15:45:56 +08:00
    snip
        1
    snip  
       2017-04-19 11:17:37 +08:00
    使用原始路径,例如 /usr/bin/cp
    expy
        2
    expy  
       2017-04-19 11:19:35 +08:00
    \wc \tr
    vjnjc
        3
    vjnjc  
       2017-04-19 11:19:52 +08:00
    占楼同问,比如我的脚本用了 alias wc=count 这污染了环境,正确的方法是不是在退出前用 unalias ?
    Jisxu
        4
    Jisxu  
       2017-04-19 11:20:09 +08:00
    unalias -a

    > man:
    unalias [-a] [name ...]
    Remove each name from the list of defined aliases. If -a is supplied, all alias definitions are removed. The
    return value is true unless a supplied name is not a defined alias.
    xiaket
        5
    xiaket  
       2017-04-19 11:25:34 +08:00
    没人觉得你这样 alias 是有问题的咩? 如果觉得 count 和 translate 太长, 你应该 alias 到 c 和 t 或者, 让用途明显一点, mywc 和 mytr 嘛.
    knightdf
        6
    knightdf  
       2017-04-19 11:25:46 +08:00
    env
    sunjourney
        7
    sunjourney  
    OP
       2017-04-19 11:37:57 +08:00
    @snip #1
    @expy #2

    类似的用法查过了。可以 \wc, 'wc', "wc", command wc ,但是其它的部分可以保证安全吗?有一天我 sb 了把 if , while 全 alias ,其它程序都崩了呢?

    @knightdf #6 env 具体怎么做呢?
    sunjourney
        8
    sunjourney  
    OP
       2017-04-19 11:42:00 +08:00
    @xiaket #5 假如 c , t 被是原生的命令并且被其它的脚本用到了呢?感觉 shell 的程序与外部环境依赖太严重了,外部的状况很容易影响到 shell script 的执行结果。真有设计失败的感觉
    xderam
        9
    xderam  
       2017-04-19 11:48:41 +08:00
    别去改 root 的 alias ,自己用自己的 alias 就好了。这个不是设计失败,应该是使用习惯不好。 linux 设计的是多用户环境,环境之间本来就有”隔离“
    sunjourney
        10
    sunjourney  
    OP
       2017-04-19 12:01:42 +08:00
    @xderam #9 说说实际的情况吧,有一个程序,用到了 wc, tr ,有另一个程序,给 git 加别名。加别名的程序读入别名 $prefix , 执行 alias {$prefix}c='git commit', alias {$prefix}r='git remote', alias {$prefix}f='git fetch'
    正常嘛,$prefix 传入的是 g ,此时 gc='git commit', gr='git remote',但现在想给 $prefix 传入 t,结果 tr 就变成了 git remote , 用到了 tr 的程序就废了。同理 $prefix 是 w, i ,这时 if, wc 都不能用了。我希望 alias 东西只影响用户自己的执行环境,用其它的脚本,它们内部用的 if ,wc, tr 还是上层环境的。全部写成 \wc \tr 是不实际的,\if 也不能这么用。
    knightdf
        11
    knightdf  
       2017-04-19 12:02:10 +08:00
    @sunjourney man env
    erobot
        12
    erobot  
       2017-04-19 12:09:48 +08:00
    @sunjourney 测试了一下, alias 是不会影响到子 shell 的,难道你是 . script.sh 或者 source script.sh 来执行脚本的??
    sunjourney
        13
    sunjourney  
    OP
       2017-04-19 12:22:49 +08:00
    @erobot #12 程序写在 zsh 的 theme 里, zsh 的 theme 都是靠 source 执行,所以就这样了。
    xiaket
        14
    xiaket  
       2017-04-19 12:37:28 +08:00
    @sunjourney 前面已经有人说了, 这不是设计失败, 是你的使用习惯问题. 另外, 我刚才列出 c 和 t 就是因为 a-z 都不是广为人知的系统命令.

    另外, 不管是用 OSX/Windows/Linux, 用户自己要作死, 操作系统都是拦不住的.
    sunjourney
        15
    sunjourney  
    OP
       2017-04-19 13:22:35 +08:00
    @xiaket #14 那具体问题怎么解决, oh-my-zsh.sh source 的主题遇到了被 alias 掉的命令(比如 Soliah.zsh-theme , date , git ,一旦被 alias )使用都会出错,可有解决方法?
    geelaw
        16
    geelaw  
       2017-04-19 13:42:03 +08:00
    答案是不要这么做就好了不要 override 系统中默认的 aliases 和 names ,也不要在脚本里面创造 aliases 。

    何必要创造问题呢?
    sunjourney
        17
    sunjourney  
    OP
       2017-04-19 13:51:20 +08:00
    @geelaw #16 嗯,只是想探讨问题而已,现在已经确定了此题无解,在程序里加了一个 warning 告知动态设定 alias 的方法对 source 到环境中的 function 与 rc scripts 有影响。
    fxxkgw
        18
    fxxkgw  
       2017-04-19 14:07:50 +08:00
    LC_ALL=C
    rrfeng
        19
    rrfeng  
       2017-04-19 14:43:42 +08:00
    用已存在的名字当作 alias 是一种什么奇怪的想法呢……
    momocraft
        20
    momocraft  
       2017-04-19 14:50:30 +08:00
    防御性编程: 在开头把需要的东西都 type 一遍,有 alias 就报错退出

    当然人总是可以作死的,比如可能有人把 type 也 alias 掉。

    不如一开始就不用容易搞出事的做法。
    sunjourney
        21
    sunjourney  
    OP
       2017-04-19 14:57:23 +08:00
    @rrfeng #19
    @momocraft #20
    这个功能就是这样,定义了 alias ${prefix}c='git commit',
    先用一个 function 将参数给 $prefix ,在 source alias ${prefix}c='git commit'
    $prefix 默认是 g ,但用户就是传入 w ,自然就变了了 alias wc='git commit',然后出现问题。
    lululau
        22
    lululau  
       2017-04-19 15:11:31 +08:00   1
    没记错的话, alias 在 non-interactive shell 里是不会被展示的。。。

    man bash | col -b | grep -i 'alias.*interactive'

    另外,强制调用 external command:

    command my_cmd
    vingz
        23
    vingz  
       2017-04-19 15:12:39 +08:00
    我从来不用 alias ,脚本的话,一次编写,多次执行,所以没必要用 alias 省事吧
    vingz
        24
    vingz  
       2017-04-19 15:13:18 +08:00
    env 可以修改环境变量,并且只对本次命令执行生效,可以解决你的问题
    xderam
        25
    xderam  
       2017-04-19 15:45:56 +08:00
    @sunjourney alias {$prefix}c='git commit' 一个胶水语言别搞那么复杂了,如果真想纠结这个问题。我记得内部命令的执行顺序是第一,然后是 PATH 里的,然后是 alias ?记不太清楚了。可以搞本鸟哥的书看看。
    如果是生产环境,别搞那么灵活。小心出现 rm -rf $var 的例子。 自己测试环境无所谓了,写个 if 判断下,或者直接写死吧。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2905 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.98.5 36ms UTC 14:01 PVG 22:01 LAX 06:01 JFK 09:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86