27

タイトルが示すように、 bashから(ほとんどの場合)呼び出されることになっているUnixスタイルのシェルユーティリティUを作成しています。

Uはbash(または一般的には親)の作業ディレクトリをどの程度正確に変更できますか?

PSシェルユーティリティchdirはまったく同じことを行うことに成功するため、効果を達成するためのプログラム的な方法が必要です。

4

8 に答える 8

35

これをしないでください。

FILE *p;
char cmd[32];
p = fopen("/tmp/gdb_cmds", "w");
fprintf(p, "call chdir(\"..\")\ndetach\nquit\n");
fclose(p);
sprintf(cmd, "gdb -p %d -batch -x /tmp/gdb_cmds", getppid());
system(cmd);

おそらく動作するでしょうが、Bash のpwdコマンドはキャッシュされていて気付かないことに注意してください。

于 2010-03-03T21:36:52.380 に答える
7

親プロセスにそれ自体を変更するように依頼する以外に、親プロセスの現在のディレクトリに影響を与える「合法的な」方法はありません。

chdirbashスクリプトでディレクトリを変更するのは外部ユーティリティではなく、組み込みコマンドです。

于 2010-03-03T21:16:23.167 に答える
5

chdir コマンドはシェルに組み込まれているため、コマンドを実行するシェルの作業ディレクトリに直接アクセスできます。シェルは通常、スクリプトの影響から自分自身を保護するのに非常に優れており、子プロセスにシェル自体の作業環境のコピーを提供します。子プロセスが終了すると、それが使用していた環境は削除されます。

できることの 1 つは、スクリプトを「ソース化」することです。これにより、ディレクトリを変更できます。これは、本質的には、コマンドを直接入力したかのように、ファイルからコマンドを実行するようにシェルに指示しているためです。つまり、シェルの環境のコピーから作業しているわけではなく、ソース時に直接作業しています。

于 2010-03-03T23:51:09.170 に答える
4

私がこれを解決した方法は、スクリプトを呼び出し、スクリプトが記述したファイルをソースするシェル エイリアスを用意することです。たとえば、

function waypoint {
    python "$WAYPOINT_DIRECTORY"/waypoint.py $@ &&
    source ~/.config/waypoint/scratch.sh
    cat /dev/null > ~/.config/waypoint/scratch.sh
}

そして次のようにwaypoint.py作成scratch.shします

cd /some/directory

これはまだ悪いことです。

于 2012-02-17T19:54:51.983 に答える
0

シェルをインタラクティブに実行していて、ターゲットディレクトリが静的である場合は、~/.bashrcファイルにエイリアスを追加するだけです。

alias cdfoo='cd theFooDir'

非対話型シェルスクリプトを処理する場合、親のBashスクリプトと子のBashスクリプトの間にプロトコルを作成できます。これを実装する方法の1つの方法は、子スクリプトにパスをファイル(など~/.new-work-dir)に保存させることです。子プロセスが終了した後、親プロセスはこのファイル(などcd `cat ~/.new-work-dir`)を読み取る必要があります。

前の段落で説明したルールを頻繁に使用する場合は、Bashソースコードをダウンロードしてパッチを適用し~/.new-work-dir、コマンドを実行するたびに作業ディレクトリがの内容に自動的に変更されるようにすることをお勧めします。このパッチでは、ニーズに合ったまったく新しいBash組み込みコマンドを実装し、実装するプロトコルを実装することもできます(この新しいコマンドは、おそらくBashメンテナによって受け入れられません)。ただし、パッチは個人的な使用と小規模なコミュニティでの使用に使用できます。

于 2011-10-12T12:36:49.603 に答える
0

できません。実生活のように、両親の道を変えることはできません:)

ただし、同様の代替手段はほとんどありません。

  1. サブシェルを開始し、そこでディレクトリを変更します (親には影響しません)。
  2. 通常はある特定のコンソール/dev/ttyXに接続し、そこでコマンドを実行します。XS0S63
  3. 実行したいコマンドを含むメッセージを親プロセスに送信します。
#include <sys/ioctl.h>

void inject_shell(const char* cmd){
  int i = 0;
  while (cmd[i] != '\0'){
    ioctl(0, TIOCSTI, &cmd[i++]);
  }
}

int main(void){
  inject_shell("cd /var\r");
  return 0;
}

コンパイルして実行します。

$ gcc inject.c -o inject
$ ./inject
cd /var
/var $

文字列がで終了すると、キーを押す(キャリッジリターン)\rを模倣する場合があります-シェルによっては、これが機能するか、試行される可能性があります。コマンドはプロセスの終了後に実行され、ユーザーに何らかのコマンドを実行するように強制しているため、これは不正行為です。Enter\r\n

于 2020-12-22T09:30:48.743 に答える