How to get the command line args passed to a running process on unix/linux systems?

点点圈 提交于 2019-11-26 11:45:31

问题


On SunOS there is pargs command that prints the command line arguments passed to the running process.

Is there is any similar command on other Unix environments?


回答1:


There are several options:

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

There is more info in /proc/<pid> on Linux, just have a look.

On other Unixes things might be different. The ps command will work everywhere, the /proc stuff is OS specific. For example on AIX there is no cmdline in /proc.




回答2:


This will do the trick:

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

Without the xargs, there will be no spaces between the arguments, because they have been converted to NULs.




回答3:


Full commandline

For Linux & Unix System you can use ps -ef | grep process_name to get the full command line.

On SunOS systems, if you want to get full command line, you can use

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

To get the full command line you need to become super user.

List of arguments

pargs -a PROCESS_ID

will give a detailed list of arguments passed to a process. It will output the array of arguments in like this:

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

I didn't find any similar command for Linux, but I would use the following command to get similar output:

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



回答4:


On Linux

cat /proc/<pid>/cmdline

get's you the commandline of the process (including args) but with all whitespaces changed to NUL characters.




回答5:


You can use pgrep with -f (full command line) and -l (long description):

pgrep -l -f PatternOfProcess

This method has a crucial difference with any of the other responses: it works on CygWin, so you can use it to obtain the full command line of any process running under Windows (execute as elevated if you want data about any elevated/admin process). Any other method for doing this on Windows is more awkward, for example.
Furthermore: in my tests, the pgrep way has been the only system that worked to obtain the full path for scripts running inside CygWin's python.




回答6:


Another variant of printing /proc/PID/cmdline with spaces in Linux is:

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

In this way cat prints NULL characters as ^@ and then you replace them with a space using sed; echo prints a newline.




回答7:


You can simply use:

ps -o args= -f -p ProcessPid



回答8:


Rather than using multiple commands to edit the stream, just use one - tr translates one character to another:

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



回答9:


In addition to all the above ways to convert the text, if you simply use 'strings', it will make the output on separate lines by default. With the added benefit that it may also prevent any chars that may scramble your terminal from appearing.

Both output in one command:

strings /proc//cmdline /proc//environ

The real question is... is there a way to see the real command line of a process in Linux that has been altered so that the cmdline contains the altered text instead of the actual command that was run.




回答10:


On Solaris

     ps -eo pid,comm

similar can be used on unix like systems.




回答11:


On Linux, with bash, to output as quoted args so you can edit the command and rerun it

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

On Solaris, with bash (tested with 3.2.51(1)-release) and without gnu userland:

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 Example (paste in terminal):

{
## 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
}

Output:

MATCH

Solaris Bash Example:

{
## 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
}

Output:

MATCH



回答12:


If you want to get a long-as-possible (not sure what limits there are), similar to Solaris' pargs, you can use this on Linux & OSX:

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



回答13:


try ps -n in a linux terminal. This will show:

1.All processes RUNNING, their command line and their PIDs

  1. The program intiate the processes.

Afterwards you will know which process to kill



来源:https://stackoverflow.com/questions/821837/how-to-get-the-command-line-args-passed-to-a-running-process-on-unix-linux-syste

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!