V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ericgui
V2EX  ›  Linux

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

  •  
  •   ericgui · 2017-01-31 22:04:26 +08:00 · 7936 次点击
    这是一个创建于 2853 天前的主题,其中的信息可能已经有所发展或是发生改变。
    下面代码都是为了说明问题,尽量简化了:
    今天是这样的,我想写一个 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 了。
    zwpaper
        2
    zwpaper  
       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   ·   实用小工具   ·   933 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:34 · PVG 06:34 · LAX 14:34 · JFK 17:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.