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

后端 未结 13 567
梦谈多话
梦谈多话 2020-11-30 16:57

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 env

相关标签:
13条回答
  • 2020-11-30 17: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
    
    0 讨论(0)
  • 2020-11-30 17:14

    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.

    0 讨论(0)
  • 2020-11-30 17:16

    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.

    0 讨论(0)
  • 2020-11-30 17:19

    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.

    0 讨论(0)
  • 2020-11-30 17:25

    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> ... ]
    
    0 讨论(0)
  • 2020-11-30 17:29

    On Linux

    cat /proc/<pid>/cmdline
    

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

    0 讨论(0)
提交回复
热议问题