unix / linuxシステムで実行中のプロセスにコマンドライン引数を渡す方法は?


回答:


307

いくつかのオプションがあります:

ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo

/proc/<pid>Linuxにはもっと多くの情報があります。

他のUnixでは、状況が異なる場合があります。psこのコマンドは、どこでも動作する/procものはOS固有のものです。AIX上の例にはありませんcmdlineでは/proc


49
Linuxでは、ps -ww -fp <pid>複数のコマンドがある場合、それらが途切れる可能性があるため、ワイド出力を指定するには、おそらく-ww(つまり)が必要になります。
シルフィード2009年

2
この-wwオプションにより、完全なコマンドライン引数(カーネルに保存されているものと同じ)にアクセスできます。参照:solarisおよびbsdがプロセスpsオプションの
GuruM

3
cat /proc/<pid>/cmdlineCygwinでも機能します。コマンドライン引数はps、オプションを指定しても表示されません。
lechup 2013年

3
Linuxでは、を取得する必要があるだけの場合args、コマンドはでps -o args -p <pid>あり、を表示するだけの場合にのみ、argsまたは-o cmdを出力しcmdます。/proc/<pid>/cmdline特権を持たないユーザーが読み込もうとしてもうまくいかない場合があります。psユーティリティが動作します。
alvits 2013

2
ヒント:の長さ/proc/<pid>/cmdlineは制限されているため(PAGE_SIZEカーネルパラメータの値にハードコードされています)、長いコマンドラインが切り捨てられて表示されます!見る stackoverflow.com / questions / 199130 /…をご覧ください。あなたは、カーネルの設定をして照会することができgetconf PAGE_SIZE、それは通常4096ですが、
t0r0X

61

これはトリックを行います:

xargs -0 < /proc/<pid>/cmdline

xargsがない場合、引数はNULに変換されているため、引数間にスペースはありません。


3
これはに短縮できますxargs -0 < /proc/<pid>/cmdline
slm

それは私の出力を切り捨てるまでです。何かアドバイスは?
johnsam

切り捨てに気づかなかった-例を挙げていただけますか?
MichaelBöckling2015

この方法では、それがインラインスペースなのか、引数の境界なのかはわかりません。
ivan_pozdeev

19

完全なコマンドライン

LinuxとUnixシステムの場合は、 ps -ef | grep process_name、完全なコマンドラインを取得。

SunOSシステムでは、完全なコマンドラインを取得する場合は、次のコマンドを使用できます。

/usr/ucb/ps -auxww | grep -i process_name

完全なコマンドラインを取得するには、スーパーユーザーになる必要があります。

引数のリスト

pargs -a PROCESS_ID

プロセスに渡される引数の詳細なリストを提供します。次のように引数の配列を出力します:

argv[o]: first argument
argv[1]: second..
argv[*]: and so on..

Linux用の同様のコマンドは見つかりませんでしたが、次のコマンドを使用して同様の出力を取得します。

tr '\0' '\n' < /proc/<pid>/environ

14

のLinux

cat /proc/<pid>/cmdline

プロセスのコマンドライン(argsを含む)を取得しますが、すべての空白がNUL文字に変更されています。


3
空白は削除されず、NULに置き換えられます。
bdonlan 2009

@bdonlanああ、私はそれをチェックしませんでした。良いキャッチ!
ローター・

4
xargs -0 echo </ proc / <pid> / cmdline。/ proc / <pid> / environでもこれを行うことができますが、そのために-n 1を追加することもできます。
camh 2009

私のシステムには/ procファイルシステムがありません:(他の解決策はありますか?
Hemant

鉱山は長い長い長いパラメーターを持つjavaプロセスです。それは私の出力を切り捨てるまでです。何かアドバイスは?
johnsam

14

あなたは使うことができpgrep-f(完全なコマンドライン)と-l(長い説明):

pgrep -l -f PatternOfProcess

この方法には他の応答との決定的な違いがあります。これはCygWinで動作するため、Windowsで実行されている任意のプロセスの完全なコマンドラインを取得できます(昇格/管理プロセスに関するデータが必要な場合は、昇格として実行します)。 。Windowsでこれを行うための他の方法は、より厄介です(たとえば)。
さらに、私のテストでは、pgrepの方法がCygWinのpython内で実行されるスクリプトの完全パスを取得するために機能た唯一のシステムでした


この1は実際には、あまりにも、元の実行可能ファイル名を出力します:$ exec -a fakename bash & [1] 14102 [1]+ Stopped exec -a fakename bash $ xargs -0 < /proc/14102/cmdline; fakename $ pgrep -l -f fakename; 14102 bash
unhammer

pgrep from procps-ng 3.3.15およびを使用している場合は機能しません3.3.12。引数なしでpidとprorgamの名前を出力するだけです。
ソコウィ

4

/proc/PID/cmdlineLinuxでスペースを使用した印刷の別のバリエーションは次のとおりです。

cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo

このようにしcatて、NULL文字を asとして出力し^@、次にを使用してそれらをスペースに置き換えますsedecho改行を出力します。


参考までに、cat -v / proc / PID / cmdline | sed 's / \ ^ @ / \ n / g'。これにより、ヌル文字が改行文字に置き換えられます。そうすることで、各引数はそれ自身の行に出力されます。そうすれば、ある引数を別の引数と区別するのが簡単になります。
TSJNachos117 2017年


2

複数のコマンドを使用してストリームを編集するのではなく、1つを使用してください-trは1つの文字を別の文字に変換します。

tr '\0' ' ' </proc/<pid>/cmdline

1

上記のすべてのテキスト変換方法に加えて、単に「文字列」を使用した場合、デフォルトでは別の行に出力されます。さらに、端末を混乱させる可能性のある文字が表示されないようにすることができるという利点もあります。

1つのコマンドで両方の出力:

文字列/ proc // cmdline / proc // environ

本当の質問は...コマンドラインに実行された実際のコマンドの代わりに変更されたテキストが含まれるように変更されたLinuxのプロセスの実際のコマンドラインを確認する方法はありますか。


1

Solarisの場合

     ps -eo pid,comm

UNIXのようなシステムでも同様に使用できます。


1

Linuxでは、bashを使用して、引用符付きの引数として出力し、コマンドを編集して再実行できます

</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
    bash -c 'printf "%q " "${1}"' /dev/null; echo

Solarisでは、bashあり(3.2.51(1)-releaseでテスト済み)、gnuユーザーランドなし:

IFS=$'\002' tmpargs=( $( pargs "${pid}" \
    | /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
    | tr '\n' '\002' ) )
for tmparg in "${tmpargs[@]}"; do
    printf "%q " "$( echo -e "${tmparg}" )"
done; echo

Linux bashの例(ターミナルに貼り付け):

{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
    "some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )

## run in background
"${argv[@]}" &

## recover into eval string that assigns it to argv_recovered
eval_me=$(
    printf "argv_recovered=( "
    </proc/"${!}"/cmdline xargs --no-run-if-empty -0 -n1 \
        bash -c 'printf "%q " "${1}"' /dev/null
    printf " )\n"
)

## do eval
eval "${eval_me}"

## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
    echo MATCH
else
    echo NO MATCH
fi
}

出力:

MATCH

Solaris Bashの例:

{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
    "some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )

## run in background
"${argv[@]}" &
pargs "${!}"
ps -fp "${!}"

declare -p tmpargs
eval_me=$(
    printf "argv_recovered=( "
    IFS=$'\002' tmpargs=( $( pargs "${!}" \
        | /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
        | tr '\n' '\002' ) )
    for tmparg in "${tmpargs[@]}"; do
        printf "%q " "$( echo -e "${tmparg}" )"
    done; echo
    printf " )\n"
)

## do eval
eval "${eval_me}"


## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
    echo MATCH
else
    echo NO MATCH
fi
}

出力:

MATCH

0

Solarisのpargsのように、可能な限り長く(どのような制限があるのか​​わからない)取得したい場合は、これをLinuxおよびOSXで使用できます。

ps -ww -o pid,command [-p <pid> ... ]

-1

ps -nLinuxターミナルで試してください 。これは表示されます:

1.すべてのプロセスRUNNING、それらのコマンドラインおよびそれらのPID

  1. プログラムはプロセスを開始します。

その後、あなたは殺すためにどのプロセスを知るでしょう

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.