Як запустити програму з іншим робочим каталогом від поточного, з оболонки Linux?


352

Використання в Linux оболонки , як почати програму з іншим робочим каталогом від поточного робочого каталогу?

Наприклад, у мене є двійковий файл, helloworldякий створює файл hello-world.txtу поточному каталозі .

Цей файл знаходиться всередині каталогу /a.

Наразі я в каталозі /b. Я хочу запустити свою програму ../a/helloworldі дістати hello-world.txtдесь у третьому каталозі /c.


5
Я виявив важкий спосіб, який suскидає робочий каталог в домашню директорію користувача, яку ви вказали, перш ніж запускати будь-які -cкоманди. Це мені дуже допомогло.
Патрік М

Відповіді:


561

Викликайте програму так:

(cd /c; /a/helloworld)

В дужках виникає породження під-оболонки. Потім ця підрозділ змінює свою робочу директорію на /c, а потім виконує helloworldз /a. Після закінчення програми підрозділ закінчується, повертаючи вас до запиту батьківської оболонки, в каталозі, з якого ви почали.

Поводження з помилками : щоб уникнути запуску програми, не змінюючи каталог, наприклад, коли помилково написано /c, зробіть виконання helloworldумовними:

(cd /c && /a/helloworld)

Зменшення використання пам’яті. Щоб уникнути втрати пам’яті на допоміжну оболонку під час виконання привіт, зателефонуйте helloworldчерез exec:

(cd /c && exec /a/helloworld)

[Дякую Джошу та Джуліано за надані поради щодо вдосконалення цієї відповіді!]


1
Будь-який спосіб передавати аргументи цій оболонці? Як у $ 1, так і $ 2?
finiteloop

2
@segfault: Підрозділ має повний доступ до оточуючої області.
Девід Шмітт

Здається, він все одно тимчасово знаходиться в цьому каталозі, чи не так?
деін

1
Ви можете передати всі аргументи, зробивши $ *, $ @ або "$ @" (якщо ви хочете, щоб аргументи поважали подвійні лапки)
Марсель Вальдес Ороско

1
Чи буде це працювати, якщо я додам цей рядок до /etc/rc.d/rc.local?
Пратік Патіл

95

Подібно до відповіді Девіда Шмітта , плюс пропозиція Джоша, але процес оболонки не залишається запущеним:

(cd /c && exec /a/helloworld)

Цей спосіб більше схожий на те, як ви зазвичай виконуєте команди на оболонці. Щоб побачити практичну різницю, ps efз кожним рішенням потрібно бігти з іншої оболонки.



25

Варіант, який не потребує підзаголовку, і вбудований для того, щоб баш

(pushd SOME_PATH && run_stuff; popd)

Демонстрація:

$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit

1
Аналогічна пропозиція була зроблена нижче Сахілом. Це не працює, якщо команда не працює. Подумайте pushd SOME_PATH && run_stuff && popd- якщо run_stuff виходить з ладу, popd не виконується.
Антон Данейко

Пізня відповідь, що залежить від налаштувань файлу bash. Bash може продовжувати виконання команд навіть після невдалої команди (на відміну від використання &&), але її можна встановити так, щоб не робити це set -eу файлі, і тоді це не вдасться popd.
Лорен

8
І все-таки я думаю, що pushd "${SOME_PATH}" && run_stuff; popdце краще, ніж нинішня відповідь, оскільки семантика pushd / popd була спеціально розроблена для такої ситуації, щоб перейти в якийсь каталог і потім повернутися до початкового.
Марсель Вальдес Орозько

Як це працює так, як визначено псевдонім, і мені потрібно пройти парам?
ДрБ

Я думаю, вам потрібно буде написати скрипт оболонки, до якого ви передатимете параметр, який би виконував серію команд, оскільки ви не можете передати параметр посеред псевдоніма. Якщо вам потрібна допомога в написанні цього запитання, вам слід задати окреме запитання і посилатися на це. Після того, як у вас буде сценарій оболонки, ви можете написати псевдонім, щоб зателефонувати своєму новому сценарію.
Лорен

19
sh -c 'cd /c && ../a/helloworld'

1
Використовували це для jexec FreeBSD для виконання команди у в'язниці у визначеній робочій директорії.
Marián Černý

11

Я завжди думаю, що інструменти UNIX слід писати у вигляді фільтрів, читати введення зі stdin та записувати вихід у stdout. Якщо можливо, ви можете змінити свій helloworld двійковий файл, щоб записати вміст текстового файлу на stdout, а не конкретний файл. Таким чином, ви можете використовувати оболонку, щоб написати файл у будь-якому місці.

$ cd ~ / b

$ ~ / a / helloworld> ~ / c / helloworld.txt


6
+1 за правильність, хоча відповідь - лише периферійна відповідь.
Девід Шмітт

8

Просто змініть останнє && "на"; " і він буде відновлювати компанію незалежно від того, якщо команда не вдасться або вдасться:

cd SOME_PATH && run_some_command ; cd -

4

Один із способів зробити це - створити сценарій оболонки для обгортки.

Сценарій оболонки змінив би поточний каталог на / c, а потім запустив / a / helloworld. Після виходу скрипта оболонки поточний каталог повертається назад до / b.

Ось приклад сценарію оболонки bash:

#!/bin/bash
cd /c
/a/helloworld

2

чому б не тримати це просто

cd SOME_PATH && run_some_command && cd -

остання команда 'cd' поверне вас до останнього каталогу pwd. Це має працювати у всіх * nix системах.


Ви пишете @mezhaka, мав би це врахувати :)
Sahil

1
Попередження: Якщо run_some_commandне вдасться, cd -не буде виконано.
starbeamrainbowlabs

1

Якщо ви завжди хочете, щоб він перейшов до / C, використовуйте абсолютний шлях, коли ви пишете файл.


0

Якщо ви хочете виконати це всередині вашої програми, я б зробив щось на кшталт:

#include <unistd.h>
int main()
{
  if(chdir("/c") < 0 )  
  {
     printf("Failed\n");
     return -1 ;
  }

  // rest of your program...

}

Він хоче робити це в оболонці-скрипті, а не в C. Також було б жахливою ідеєю переробляти двійковий файл.

-1

з поточного каталогу надайте повний шлях до каталогу скриптів для виконання команди

/root/server/user/home/bin/script.sh

1
Це зовсім не змінює робочий каталог - я думаю, ви відповідаєте на інше запитання на те, що було задано.
Toby Speight

Приїхав сюди, щоб знайти відповідь на питання, на яке ви відповіли. Дякую! lol
kfrncs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.