web-dev-qa-db-ja.com

UNIX / Linuxシステムで実行中のプロセスに渡されるコマンドライン引数を取得する方法は?

SunOSには、実行中のプロセスに渡されるコマンドライン引数を出力するpargsコマンドがあります。

他のUnix環境にも同様のコマンドはありますか?

177
Hemant

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

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

Linuxの/proc/<pid>に詳細があります。ご覧ください。

他のUnixでは状況が異なる場合があります。 psコマンドはどこでも動作します。/procのものはOS固有です。たとえば、AIXでは、/proccmdlineがありません。

278
markus_b

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

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

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

60

完全なコマンドライン

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
16
LOGAN

オンLinux

cat /proc/<pid>/cmdline

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

14
lothar

pgrep-f(完全なコマンドライン)および-l(詳細な説明)と共に使用できます。

pgrep -l -f PatternOfProcess

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

12

Linuxでスペースを使用して/proc/PID/cmdlineを印刷する別のバリ​​アントは次のとおりです。

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

このようにcatNULL文字^@として出力し、sedを使用してスペースに置き換えます。 echoは改行を出力します。

3
Diego

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

tr '\0' ' ' </proc/<pid>/cmdline
2
Tom Evans

次を使用できます。

ps -o args= -f -p ProcessPid
1
Mitar

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
1
Iwan Aucamp

Solarisの場合

     ps -eo pid,comm

unixのようなシステムで同様の機能を使用できます。

1
HuntM

テキストを変換する上記のすべての方法に加えて、単に「文字列」を使用すると、デフォルトで個別の行に出力が作成されます。さらに、端末をスクランブルする可能性のある文字が表示されないようにするという利点もあります。

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

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

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

1

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

1.実行中のすべてのプロセス、コマンドライン、およびPID

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

その後、どのプロセスを終了するかがわかります

0
repzero

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

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