Привет друзья. Частый вопрос: Можно ли в bash скрипте, каким-то образом временно изменить текущий рабочий каталог для выполнения команды, но остаться в каталоге запуска?

Да всё можно, а если говорят что нельзя, то это пиздёшь. Формулировка вопроса конечно замысловатая. Сходу в голову приходит вариант использовать cd (Change Directory), тип такого:

cd /tmp/test && ./exec_command

После запуска команды, переходим в каталог /tmp/test и выполняем exec_command. Логично? Логично! А что если после запуска этой команды, я хочу остаться в том же каталоге из которого запускал эту команду.

Вот наглядно что происходит:

1. > pwd
2. /root
3. > cd /tmp/test && ./exec_command
4. > pwd
5. /tmp/test

В самой последней строке видим, что каталог изменился. А я хочу оставаться в root!

Что делать? Есть способы, которые я лично использую в своих bash скриптах. Возможно есть какие-то и другие варианты, если знаешь, пиши в комментарии, будет полезно.

Способ первый:

Добавим в скрипт exec_command такой код:

ls

Запускаем то же самое в круглых скобках:

1. > pwd
2. /root
3. > (cd /tmp/test && ./exec_command)
4. a.txt  b.txt  c.txt  exec_command
5. > pwd
6. /root
7. > ls
8. profit

Что мы видим: после выполнения команды в скобках, отработала команда ls из скрипта и вывела на экран содержимое каталога /tmp/test. Как только произошла магия, всё вернулось обратно в каталог root и вывело на экран содержимое каталога root.

Способ второй pushd/popd:

1. > pwd
2. /root
3. > pushd /tmp/test
4. /tmp/test ~
5. > ./exec_command
6. a.txt  b.txt  c.txt  exec_command
7. > popd
8. ~
9. > pwd
10. /root

Механика аналогична первому способу. Но используются древние, инопланетные технологии pushd и popd, это коробочные аналоги cd из 80-х годов. Местоположение предыдущих каталогов сохраняется в стек (массив). А потом уже из этого стека можно вытаскивать необходимое. Погугли если интересно, есть статейки.

Ну и бонусом третий способ:

1. > pwd
2. /root
3. cd /tmp/test && ./exec_command
4. a.txt  b.txt  c.txt  exec_command
5. > pwd
6. /tmp/test
7. > cd -
8. /root

Здесь используем чистый cd, но для возврата в предыдущий каталог используем cd с параметром «-».

В 99% случаев никто этим не пользуется, все привыкли в скриптах использовать cd туда-сюда с указанием полных/относительных путей. Но если посмотреть в скрипты коммерческих продуктов, в них активно используются методы с pushd и popd.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Легаси? Возможно. Тут наверное дело больше в элегантности. У каждого свои бест-практики, нет неправильных решений. Если задача приносит ожидаемый результат, значит ты всё сделал правильно.

Ладно, изучай, а я пошёл писать следующий пост про обработку сигналов. И нас тут уже 13к, идем дальше!