Linuxシェルを使用して、現在の作業ディレクトリとは異なる作業ディレクトリでプログラムを起動する方法を教えてください。
たとえば、現在のディレクトリにファイルhello-world.txt
を作成するバイナリファイルhelloworld
があります。このファイルはディレクトリ/a
の中にあります。現在私はディレクトリ/b
にいます。私のプログラムを../a/helloworld
で起動し、hello-world.txt
を3番目のディレクトリ/c
のどこかに入れたいと思います。
このようにプログラムを呼び出します。
(cd /c; /a/helloworld)
括弧はサブシェルを生成します。このサブシェルは、その作業ディレクトリを/c
に変更し、/a
からhelloworld
を実行します。プログラムが終了すると、サブシェルは終了し、親シェルのプロンプトに戻ります。開始ディレクトリに戻ります。
エラー処理:ディレクトリを変更せずにプログラムを実行しないようにします。 /c
のスペルを間違えた場合は、helloworld
の実行を条件付きにします。
(cd /c && /a/helloworld)
メモリ使用量の削減:hello worldの実行中にサブシェルがメモリを浪費しないようにするには、execを介してhelloworld
を呼び出します。
(cd /c && exec /a/helloworld)
[この答えを改善するためのヒントを与えてくれてありがとう JoshとJuliano !]
David Schmitt の答えにJoshの提案を加えたものに似ていますが、Shellプロセスを実行したままにしないでください。
(cd /c && exec /a/helloworld)
この方法は、通常シェルでコマンドを実行する方法に似ています。実際の違いを確認するには、各ソリューションで別のシェルからps ef
を実行する必要があります。
sh -c 'cd /c && ../a/helloworld'
サブシェルを必要とせず、bashに組み込まれているオプション
(pushd SOME_PATH && run_stuff; popd)
デモ:
$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit
私はいつもUNIXツールはフィルタとして書かれ、標準入力から入力を読み、標準出力に出力を書くべきだと思います。可能であれば、テキストファイルの内容を特定のファイルではなく標準出力に書き込むようにhelloworldバイナリを変更することができます。そうすれば、シェルを使ってどこにでもファイルを書き込むことができます。
$ cd〜/ b
$〜/ a/helloworld>〜/ c/helloworld.txt
最後の "&&"を ";"に変更するだけです。そして、コマンドが失敗したか成功したかに関わらず、cdは返されます。
cd SOME_PATH && run_some_command ; cd -
そのための1つの方法は、ラッパーシェルスクリプトを作成することです。
シェルスクリプトは現在のディレクトリを/ cに変更してから/ a/helloworldを実行します。シェルスクリプトが終了すると、現在のディレクトリは/ bに戻ります。
これがbashシェルスクリプトの例です。
#!/bin/bash
cd /c
/a/helloworld
常に/ Cに移動したい場合は、ファイルを書き込むときに絶対パスを使用してください。
単純にしない
cd SOME_PATH && run_some_command && cd -
最後の 'cd'コマンドで最後のpwdディレクトリに戻ります。これはすべての* nixシステムで機能するはずです。
あなたがあなたのプログラムの中でこれを実行したいならば、私は以下のようにするでしょう:
#include <unistd.h>
int main()
{
if(chdir("/c") < 0 )
{
printf("Failed\n");
return -1 ;
}
// rest of your program...
}
現在のディレクトリから、コマンドを実行するためのスクリプトディレクトリへのフルパスを指定します。
/root/server/user/home/bin/script.sh