Как Bash может выполнить команду в другом контексте каталога?

94

У меня есть обычная команда, которая вызывается из очень определенных каталогов. Для этой программы в / bin находится только один исполняемый файл, и текущий рабочий каталог очень важен для его правильной работы. Сценарий влияет на файлы, которые находятся внутри каталога, в котором он запущен.

Теперь у меня также есть собственный сценарий оболочки, который выполняет некоторые действия в одном каталоге, но мне нужно вызвать эту команду, упомянутую выше, как если бы она находилась в другом каталоге.

Как это сделать в сценарии оболочки?

Марти Уоллес
источник

Ответы:

39

Для этой цели вы можете использовать cdвстроенную команду или встроенные команды pushdи popd. Например:

# do something with /etc as the working directory
cd /etc
:

# do something with /tmp as the working directory
cd /tmp
:

Вы используете встроенные команды, как и любую другую команду, и можете изменять контекст каталога сколько угодно раз в сценарии.

Тодд А. Джейкобс
источник
4
Также cd -в оболочке POSIX есть возможность вернуться в предыдущий каталог. Тем не менее, (а) pushdи popdдействительно предназначены для интерактивного использования, и (б) не всегда безопасно предполагать, что вы можете cdвернуться туда, откуда начали, особенно в сложных подсистемах, которые могут использовать внутренние ограничительные разрешения (см. Stackoverflow.com/questions/ 10555284 /… ).
geekosaur
3
Использование подоболочки - гораздо лучшее решение
josh123a123
Для сценариев подоболочка, вероятно, будет лучшей идеей ... Однако я действительно рад узнать об этом popd.
connorbode
Не могли бы вы объяснить, что :здесь означает символ?
Вадим Котов
2
@VadimKotov Я думаю, что это действительно запретная игра. Соответствующий раздел man bashчитает: : [arguments]Нет эффекта; команда не делает ничего, кроме расширения аргументов и выполнения любых указанных перенаправлений. Статус возврата равен нулю.
boycy
218

Использование cdв подоболочке; сокращенный способ использования подоболочки - круглые скобки.

(cd wherever; mycommand ...)

Тем не менее, если ваша команда имеет среду, которая ей требуется, она действительно должна гарантировать, что сама среда, вместо того, чтобы возлагать ответственность на все, что может захотеть ее использовать (если только это не внутренняя команда, используемая в очень конкретных обстоятельствах в контексте хорошо определил более крупную систему, так что любой вызывающий уже должен гарантировать среду, которую он требует). Обычно это будет своего рода оболочка сценария оболочки.

гикозавр
источник
Вы также можете вставить \после каждой ;для многострочных команд в том же контексте.
Chiramisu
36
(cd /path/to/your/special/place;/bin/your-special-command ARGS)
bmargulies
источник
20

Если вы хотите вернуться в текущий рабочий каталог:

current_dir=$PWD;cd /path/to/your/command/dir;special command ARGS;cd $current_dir;
  1. Мы устанавливаем переменную, current_dirравную вашемуpwd
  2. после этого мы отправимся туда, cdгде вам нужно запустить свою команду
  3. затем мы запускаем команду
  4. затем мы cdвернемся к нашей переменнойcurrent_dir

Другое решение от @apieceofbart pushd && YOUR COMMAND && popd

abc123
источник
4
или вы могли бы сделатьpushd && YOUR COMMAND && pulld
apieceofbart
4
@apieceofbart, я думаю, вы имели в виду popdвместоpulld .
Константин