繁体   English   中英

Bash中“ if”条件中的“ cd”在“ if”之后不会更改当前目录

[英]“cd” inside “if” condition in Bash does not change the current directory after “if”

我试图在Bash脚本的“ if”条件内执行“ cd”。 它在“ if”之后保留在同一目录中。 因此,我必须在“ if”之外执行“ cd”,然后使用$? 值如果。 有办法避免使用此额外步骤吗? 最快的方法是什么?

查看我的代码的三个变体:

#!/bin/bash

set +e

# If I write the following:

if ! (rm -rf sim && mkdir sim && cd sim); then
    echo $0: Cannot prepare simulation directory
    exit 1
fi

# it does not change the current directory

echo $PWD

# Also, if I write the following:

if ! rm -rf sim || ! mkdir sim || ! cd sim; then
    echo $0: Cannot prepare simulation directory
    exit 1
fi

# it also does not change the current directory

echo $PWD

# In order to change the current directory, I need to write:

rm -rf sim && mkdir sim && cd sim

if [ $? -eq 1 ]; then
    echo $0: Cannot prepare simulation directory
    exit 1
fi

# Now it prints .../sim

echo $PWD
cd ..

# Is it possible to write it without an additional line with $?

exit

bash中的括号创建了一个子外壳-一个fork() -从外壳副本中复制出它自己的环境变量,它自己的当前目录等。 因此,在您的第一次尝试中, cd仅在结束括号结束子shell之前生效。 (POSIX并不严格要求这种subshel​​l行为,但是它确实要求括号创建的环境具有其自己的工作目录,因此cd的作用将作用于所有符合标准的shell,无论该shell是否实际使用了在所有情况下都为fork() )。

当您不想创建子外壳时,请使用大括号而不是括号进行分组。 那是:

if ! { rm -rf sim && mkdir sim && cd sim; }; then
    echo "$0: Cannot prepare simulation directory"
    exit 1
fi

也就是说,您的第二种方法非常有效 (尽管编写起来很笨拙,而不是传统的习惯用语)。

bash <<'EOF'
cd /tmp
echo "Starting in $PWD"
if ! rm -rf sim || ! mkdir sim || ! cd sim; then
    echo "$0: Cannot prepare simulation directory"
    exit 1
fi
echo "Ending in $PWD"
EOF

...正确发出:

Starting in /tmp
Ending in /tmp/sim

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM