/proc
私が知っている限り、LinuxにはPOSIXの一部ではないディレクトリとファイルシステムがあります。各サブディレクトリには、対応するPIDプロセスの実際の作業ディレクトリを指す/proc/$PID
シンボリックリンクがあります(このリンクは常に最新の状態です)。cwd
cwd
このシンボリックリンクは、他のシェルを使用したり、2つのシェル(正式に作業ディレクトリ)間でファイルを交換したりするなど、特定のユースケースに便利です。
POSIX機能のみを使用してこのようなものを簡単に取得する方法はありますか?
問題に関する追加情報
より正確に説明すると、接続と環境変数lileである必要はありません。$<PID>_CWD
それも大丈夫です。一見すると、そのような解決策が存在するとは信じていません。簡単に参照できる必要があります(シンボリックリンクや環境変数など)、他のプロセスが作業ディレクトリを切り替えるたびに常に最新の状態に保たれる必要があります。
ソリューションがPOSIXである必要はありません。最も重要な側面は移植性ですが、POSIXは確実に保証されています。
答え1
lsof
BSDにはデフォルトでインストールされていないため、BSDで使用するにはインストールする必要があります。
シェルスクリプトを作成します。
#!/bin/sh
lsof -p $1 | grep cwd | awk '{print $9}'
パスのディレクトリにコピーします。最初のパラメータIEで指定されたPIDの作業ディレクトリを印刷します。
$ script 1987
/home/enedil
答え2
POSIXは、関連していないプロセスに関する情報を取得するための多くの機能を提供しません。ただps
、実際には現在のディレクトリに関する情報を提供していません。 CレベルのAPIも良いことはありません(実際に検索された情報のほとんどは、ps
出力を解析するだけで検索できます)。
興味深いことに、POSIXは反対の操作を実行する移植可能な方法を提供します。つまり、ファイルが与えられたら、次を呼び出して、どのプロセスがファイルを開いているかを確認できます。fuser
。次のコードスニペットは、特定の作業ディレクトリを持つプロセスのPIDを一覧表示します。
fuser -f "$directory_name" 2>&1 | sed -e '$!d' -e 's/.*://' -e 's/ */\
/' | sed -n 's/c$//p'
実際に移植可能な方法でプロセスに関する情報を取得するには、次のようにします。ラソフ。 lsofの作成者は、さまざまなUNIXバリアントに関する情報を取得するさまざまな方法を実装する作業を行いました。
日常的な検索の場合:
lsof -a -p "$pid" -d cwd
自動解析の場合:
lsof -a -p "$pid" -d cwd -F n | sed -e '1d' -e '2s/^n//'
改行文字はlsof
文字列に置き換えられます\n
。
一部の Unix バリアントでは、サードパーティ製ソフトウェアを必要としないメソッドを提供していますが、これらのメソッドは各バリエーションによって異なります。非常に関連性の高い注意事項については、以下を参照してください。ファイル記述子リンクの移植性
一部の古いUnixにはps
setuidルートがあり、カーネルメモリを読み取るので、setuidバイナリを使用することがこの情報を取得する唯一の方法です。
答え3
私は自分の答えに貢献します。
/proc/$PID/cwd
質問に焦点を当てたインタラクティブシェルのコンテキストでは、1つのオプションは、Bashが提供する自動化の機会を使用してリンクを自動的に維持することです。
PROMPT_COMMAND="ln -sfT \$(pwd) ~/$LINK_NAME"
f
リンクが頻繁に上書きされるため、このオプションが必要です。このT
オプションは必須です。それ以外の場合はf
正常に動作しているようです。
たとえば、次のようにシェルに協力させることができます~/.bashrc
。
if [ -v CWD_LINK_NAME ]; then
PROMPT_COMMAND='ln -sfT "$(pwd)" "'$CWD_LINK_NAME'";'$PROMPT_COMMAND
declare -r CWD_LINK_NAME
function rm_cwd_link() {
rm "$CWD_LINK_NAME"
}
trap rm_cwd_link EXIT
fi
シェルまたは端末を関連するCWD_LINK_NAME
値に設定して実行を実行できます。前任者。CWD_LINK_NAME="~/$SOME_ROLE_NAME" gnome-terminal
別のオプションは、同じ概念を使用して可変作業ディレクトリ内の船を追跡することです。このトレースは両方に基づいています。@ギルスそして@nedil貢献する:
PROMPT_COMMAND="PEAR_WD=\$(lsof -p $PID | awk '/cwd/{print \$9}')"
$PROMPT_COMMAND
ただし、これはあまり正確ではなく便利ですが、他のシェルに設定できないまれな場合には、これが唯一の方法です。
私は最初のオプションを好みます(他の貢献がある場合は答えを選択する前にまだ待っています)。