Скобки в bash создают вложенную оболочку - fork()
-открытую копию оболочки с собственными переменными среды, собственным текущим каталогом и т. Д .;таким образом, в вашей первой попытке cd
вступил в силу только до тех пор, пока закрывающая пара не закончила подоболочку. (POSIX не требует строго такого поведения подоболочки, но требует , чтобы среда, создаваемая в скобках, имела свой собственный рабочий каталог, поэтому эффекты cd
будут применены ко всем стандартнымсовместимые оболочки, независимо от того, использует ли эта оболочка 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