Чи є спосіб виконати команду в іншому каталозі, не виконуючи cd
її? Я знаю, що я міг просто входити cd
і cd
виходити, але мене просто цікавлять можливості пройти зайві кроки :)
Чи є спосіб виконати команду в іншому каталозі, не виконуючи cd
її? Я знаю, що я міг просто входити cd
і cd
виходити, але мене просто цікавлять можливості пройти зайві кроки :)
Відповіді:
Я не знаю, чи зараховується це, але ви можете зробити підзаголовок:
$ (cd /var/log && cp -- *.log ~/Desktop)
Каталог змінюється лише для цієї підкашти, тож ви уникаєте роботи, необхідної для cd -
цього.
$ (cd /var/log && cp *.log ~/Desktop)
. Таким чином, якщо каталог не існує, подальші команди не виконуються.
У деяких програмах є параметри, за допомогою яких ви можете самі їм сказати chdir (2) (наприклад, GNU tar 's -C
/ --directory
).
Поза такими програмами хоч щось доведеться чудовати . Ви можете написати та використати якусь компільовану "двійкову" програму замість того, щоб оболонка це робила, але це, ймовірно, не принесе великої користі.
У коментарі до іншої відповіді ви навели приклад:
execindirectory -d /var/log "cp *.log ~/Desktop"
Оскільки *.log
шаблон розширюється самою оболонкою (не cp ), вам доведеться щось chdir до каталогу, перш ніж оболонка оцінить вашу команду.
Якщо вам просто цікаво уникати "CD back", тоді ви можете скористатися підзаголовком, щоб ізолювати ефект CD від вашого робочого екземпляра оболонки.
(cd /path/to/dir && some command)
Ви можете упакувати це у функції оболонки. (Я викинув цю -d
опцію з вашого прикладу використання, оскільки ця команда мало сенсу, якщо каталог насправді необов’язковий.)
runindir() { (cd "$1" && shift && eval "$@"); }
runindir /var/log 'cp *.log ~/Desktop' # your example
runindir /var/log cp \*.log \~/Desktop # eval takes multiple args
runindir /var/log cp \*.log ~/Desktop # it is okay to expand tilde first
Щоб не підірвати значення відповідей інших людей, але я вважаю, що ви хочете, це таке:
(cd /path/to && ./executable [ARGS])
Зверніть увагу на парени для виклику cd
в під оболонці.
Ось те, що повинно вас cd
повернути туди, де ви були (використовуючи Bash), оскільки не забуваючи це зробити, здається, метою цього питання:
# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir
run-your-command
# Get back where you were at the beginning.
popd
(EDIT: трохи коротша версія, завдяки @ Random832)
pushd other-dir
, а неpushd .; cd other-dir
На жаль, ваш приклад:
execindirectory -d /var/log "cp *.log ~/Desktop"
не потребує змін до режисера, тому що
cp /var/log/*.log ~/Desktop
зробив би те саме. Ви не можете наблизитися до своєї реальної проблеми? Тому що ми можемо знати і краще рішення для цього.
Складний спосіб вирішити вашу проблему, яка далека від елегантності рішення Майкласа, - це використання знахідки, яка має перемикач '-execdir', який слід виконати в режимі, де знайдений файл. Погано прийнято до вашого прикладу:
find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"
Можливо, це корисно для вашої реальної проблеми. -okdir замість -execdir попросить підтвердити кожне виклик.
-okdir та -execdir, можливо, знадобиться встановити gnu-find, який зазвичай використовується в Linux.
Як щодо ./your/path/command.sh
?
execindirectory -d /var/log "cp *.log ~/Desktop"
.
echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory
. Ви можете докласти трохи більше зусиль, якщо ви хочете, щоб він фактично підтримував параметри "тегів", таких як-d
і подібні речі.