Shell Script 里的 cd 命令,很有点意思,有点困惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ericgui
V2EX    Linux

Shell Script 里的 cd 命令,很有点意思,有点困惑

  •  
  •   ericgui 2017-01-31 22:04:26 +08:00 8327 次点击
    这是一个创建于 3182 天前的主题,其中的信息可能已经有所发展或是发生改变。
    下面代码都是为了说明问题,尽量简化了:
    今天是这样的,我想写一个 script ,只有一行:
    文件路径和名称:$PATH/cdtest.sh
    #!/bin/bash
    cd /data/someproject
    也就是说,我想在任何目录下,直接跳转至指定目录(这里是 /data/someproject )
    然后呢,自然就很显然没反应。只能用 source cdtest.sh 这个命令,才能实现跳转目录。
    查了半天,才知道, script 执行的时候,创建了一个子 shell ,子 shell 的存在依赖于 current directory ,那显然就不能跳转目录了

    现在问题来了,我做了这样的改变:
    我先判断, pwd 是否是我的目标目录,如果是,就执行 git pull 命令,由于 git pull 命令必须在正确的 git directory 才能 pull 下来代码,所以如果目录不对,就产生 fatal error 。

    文件路径和名称:$PATH/pullsomeproject.sh

    1 #!/bin/bash
    2
    3 target='/data/someproject'
    4
    5 if [ $(pwd) = $target ]; then
    6 git pull [email protected]:myaccount/someproject.git
    7 else
    8 cd /data/someproject
    9 pullsomeproject.sh
    10 fi


    这个在任意目录下都可以执行成功。

    说明什么?
    说明在其他目录下,执行了 cd /data/someproject ,实现了目录跳转至 /data/someproject 这个目录,而且又执行了 pullsomeproject.sh 这个脚本。

    但是,上面的代码,执行成功之后,仍然留在 pwd ,就是说,没有实现跳转目录。

    所以这就尼玛困惑了。到底执行了 cd 这个命令么吗?如果没执行,那 git pull 怎么成功了呢(如果你在其他目录执行 git pull ,会有错误)
    如果执行了,为啥没有实现跳转目录?

    当然了,如果用 source pullsomeproject.sh ,那目录也跳转了, git pull 也执行了。
    所以就感觉非常邪门。
    18 条回复    2017-02-01 15:37:39 +08:00
    hzlez
        1
    hzlez  
       2017-01-31 22:19:18 +08:00
    我理解,就和函数的入栈出栈一样,子 shell 调用结束,就回到你执行时的 current directory 了。
    ikw
        2
    ikw  
       2017-01-31 22:20:06 +08:00 via iPhone
    有点没看明白,但是
    cd 只是在脚本执行的子 shell 里换目录了,按说也是可以执行成功的
    git 在 2.几以后的版本可以用 -C 指定目录
    xpol
        3
    xpol  
       2017-01-31 22:25:00 +08:00 via iPhone
    git 1.8.5+ 就可以 git -C <directory> ... 了。
    likuku
        4
    likuku  
       2017-01-31 22:25:08 +08:00
    脚本里写 cd 是没问题的啊,我一直这么用,在 bash 环境 / bash some.sh 方式来显式执行。
    wohenyingyu02
        5
    wohenyingyu02  
       2017-01-31 22:30:37 +08:00 via iPhone
    你都知道是新开的 shell 了, cd 跳转的是新开的 shell 的当前目录,不是你正在看的 shell 啊, pwd 也是检查新开的 shell 当前目录,执行完关闭新开的 shell ,为何会影响你在使用的 shell 呢
    larsenlouis
        6
    larsenlouis  
       2017-01-31 22:30:43 +08:00
    #!/bin/bash
    cd "$(realpath "/cygdrive/b/")"
    ls
    wohenyingyu02
        7
    wohenyingyu02  
       2017-01-31 22:32:33 +08:00 via iPhone
    @wohenyingyu02 好比你开了两个 shell 窗口,你在其中一个 cd xxx 并不会影响另一个
    yyai3
        8
    yyai3  
       2017-01-31 22:36:11 +08:00
    subshell 继承原 shell 的环境变量和路径, subshell 里的 cd 及新增变量不会影响到原 shell
    ericgui
        9
    ericgui  
    OP
       2017-01-31 22:39:13 +08:00
    @wohenyingyu02 哦,你这一解释我就明白了。 cd 之后新跳转的目录,只是我看不到而已。
    ericgui
        10
    ericgui  
    OP
       2017-01-31 22:40:38 +08:00
    @wohenyingyu02 恩,是的,我看到的是 current directory , script 的子 shell 执行了 cd ,做了跳转,然后执行了 git pull

    谢谢!豁然开朗!
    ericgui
        11
    ericgui  
    OP
       2017-01-31 22:41:47 +08:00
    @yyai3
    @wohenyingyu02 二位说的对。谢谢!
    KentY
        12
    KentY  
       2017-02-01 00:06:34 +08:00
    我的 pullall, 你可以参考. git 版本如果不是很老, 可以-C
    https://github.com/sk1418/myScripts/blob/master/shell/pullall.sh
    ericgui
        13
    ericgui  
    OP
       2017-02-01 01:52:33 +08:00
    @xpol 死了,谢谢。那就不用费劲判断目录了
    binarylu
        14
    binarylu  
       2017-02-01 01:54:25 +08:00
    cd 不是命令,没有一个对应的 bin 程序, cd 是 shell 的关键字,由 shell 直接执行
    webjin1
        15
    webjin1  
       2017-02-01 02:34:11 +08:00 via Android
    @binarylu cd 是 shell 内键命令
    hosiet
        16
    hosiet  
       2017-02-01 10:23:25 +08:00 via Android
    我觉得直接把 cd 理解成系统调用比较好,直接对应 chdir(2),不是外部命令,只是运行中的 shell 改了改自己的工作目录而已。
    owt5008137
        17
    owt5008137  
       2017-02-01 11:59:30 +08:00 via Android
    1. 当前目录属于环境(变量)
    2. 除了内建命令外, shell 里执行一个程序都是新开子进程的(包括执行一个脚本文件)
    3. 子进程的环境(变量)变化不会影响父进程。

    你理解了这三条就明白为什么了
    ericgui
        18
    ericgui  
    OP
       2017-02-01 15:37:39 +08:00
    @owt5008137 谢谢,这次算是彻底明白了。非常感谢!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1039 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 273ms UTC 18:37 PVG 02:37 LAX 11:37 JFK 14:37
    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