SunOSには、実行中のプロセスに渡されるコマンドライン引数を出力するpargs
コマンドがあります。
他のUnix環境にも同様のコマンドはありますか?
いくつかのオプションがあります:
ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo
Linuxの/proc/<pid>
に詳細があります。ご覧ください。
他のUnixでは状況が異なる場合があります。 ps
コマンドはどこでも動作します。/proc
のものはOS固有です。たとえば、AIXでは、/proc
にcmdline
がありません。
これはトリックを行います:
xargs -0 < /proc/<pid>/cmdline
Xargsがない場合、引数はNULに変換されているため、引数間にスペースはありません。
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
オンLinux
cat /proc/<pid>/cmdline
プロセスのコマンドライン(引数を含む)を取得しますが、すべての空白がNUL文字に変更されます。
Linuxでスペースを使用して/proc/PID/cmdline
を印刷する別のバリアントは次のとおりです。
cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo
このようにcat
は NULL文字 を^@
として出力し、sed
を使用してスペースに置き換えます。 echo
は改行を出力します。
複数のコマンドを使用してストリームを編集するのではなく、1つを使用するだけです-trは1つの文字を別の文字に変換します。
tr '\0' ' ' </proc/<pid>/cmdline
次を使用できます。
ps -o args= -f -p ProcessPid
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
Solarisの場合
ps -eo pid,comm
unixのようなシステムで同様の機能を使用できます。
テキストを変換する上記のすべての方法に加えて、単に「文字列」を使用すると、デフォルトで個別の行に出力が作成されます。さらに、端末をスクランブルする可能性のある文字が表示されないようにするという利点もあります。
1つのコマンドで両方の出力:
文字列/ proc // cmdline/proc // environ
本当の質問は...変更されたLinuxのプロセスの実際のコマンドラインを表示して、実行された実際のコマンドの代わりにcmdlineに変更されたテキストが含まれるようにする方法です。
linuxターミナルで「ps -n」を試してください。これは表示されます:
1.実行中のすべてのプロセス、コマンドライン、およびPID
その後、どのプロセスを終了するかがわかります
Solarisの pargs と同様に、可能な限り長く(どのような制限があるかわからない)したい場合は、LinuxとOSXでこれを使用できます。
ps -ww -o pid,command [-p <pid> ... ]