Bagaimana cara mendapatkan args baris perintah yang diteruskan ke proses yang berjalan pada sistem unix / linux?

203

Pada SunOS ada pargsperintah yang mencetak argumen baris perintah yang diteruskan ke proses yang sedang berjalan.

Apakah ada perintah serupa di lingkungan Unix lain?

Hemant
sumber
4
tr \\0 ' ' < /proc/<pid>/cmdline
Dmitry Grigoryev

Jawaban:

307

Ada beberapa opsi:

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

Ada lebih banyak info di /proc/<pid>Linux, lihat saja.

Di Unix lain, segalanya mungkin berbeda. The psperintah akan bekerja di mana-mana, yang /prochal ini OS tertentu. Misalnya pada AIX tidak ada cmdlinedi /proc.

markus_b
sumber
49
di linux, Anda mungkin perlu -ww (yaitu ps -ww -fp <pid>) untuk menentukan output lebar karena jika ada beberapa perintah, mereka bisa terputus.
Silfheed
2
yang -wwpilihan memungkinkan akses ke argumen baris perintah penuh (sebanyak disimpan oleh kernel). Lihat Juga: bagaimana solaris dan bsd mendapatkan parameter commandline yang tidak digunakan untuk proses dan opsi ps
GuruM
3
cat /proc/<pid>/cmdlinejuga berfungsi di Cygwin, di mana argumen garis cmd tidak ditampilkan psdengan opsi apa pun.
lechup
3
Di Linux, jika Anda hanya perlu mendapatkan args, perintahnya adalah ps -o args -p <pid>dan itu hanya akan mencetak argsatau menggunakan -o cmdjika Anda hanya perlu melihatnya cmd. Mencoba membaca /proc/<pid>/cmdlinetidak akan selalu berhasil untuk pengguna yang tidak memiliki privasi. The psutilitas akan bekerja.
alvits
2
Petunjuk: panjangnya /proc/<pid>/cmdlineterbatas (kode keras untuk nilai parameter kernel PAGE_SIZE), jadi lebih lama baris perintah masih ditampilkan terpotong! Lihat stackoverflow.com/questions/199130/… untuk info lebih lanjut. Anda dapat menanyakan pengaturan kernel Anda getconf PAGE_SIZE, biasanya 4096.
t0r0X
61

Ini akan melakukan trik:

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

Tanpa xargs, tidak akan ada spasi di antara argumen, karena mereka telah dikonversi ke NUL.

Michael Böckling
sumber
3
Ini dapat disingkat menjadi xargs -0 < /proc/<pid>/cmdline.
slm
Ini masih memotong output saya. Adakah saran?
johnsam
Tidak pernah melihat pemotongan apa pun - dapatkah Anda memberi contoh?
Michael Böckling
Dengan cara ini, Anda tidak bisa mengatakan apakah itu ruang inline atau batas argumen.
ivan_pozdeev
19

Baris perintah penuh

Untuk Sistem Linux & Unix dapat Anda gunakan ps -ef | grep process_nameuntuk mendapatkan baris perintah penuh.

Pada sistem SunOS, jika Anda ingin mendapatkan baris perintah penuh, Anda dapat menggunakannya

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

Untuk mendapatkan baris perintah penuh, Anda harus menjadi pengguna super.

Daftar argumen

pargs -a PROCESS_ID

akan memberikan daftar terperinci argumen yang diteruskan ke suatu proses. Ini akan menampilkan array argumen seperti ini:

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

Saya tidak menemukan perintah serupa untuk Linux, tetapi saya akan menggunakan perintah berikut untuk mendapatkan hasil yang serupa:

tr '\0' '\n' < /proc/<pid>/environ
LOGAN
sumber
14

Di Linux

cat /proc/<pid>/cmdline

dapatkan baris perintah dari proses (termasuk args) tetapi dengan semua spasi putih berubah menjadi karakter NUL.

lothar
sumber
3
Spasi tidak dihapus, diganti dengan NUL.
bdonlan
@bdonlan Ah, saya tidak memeriksanya. Tangkapan yang bagus!
lothar
4
xargs -0 echo </ proc / <pid> / cmdline. Anda juga dapat melakukan ini dengan / proc / <pid> / environment, meskipun Anda mungkin ingin menambahkan -n 1 untuk itu.
camh
Pada sistem saya tidak ada / proc filesystem :( ada solusi lain?
Hemant
Tambang adalah proses java dengan parameter yang sangat panjang. Ini masih memotong output saya. Adakah saran?
johnsam
14

Anda dapat menggunakan pgrepdengan -f(baris perintah penuh) dan -l(deskripsi panjang):

pgrep -l -f PatternOfProcess

Metode ini memiliki perbedaan penting dengan salah satu respons lain: ia bekerja di CygWin , sehingga Anda dapat menggunakannya untuk mendapatkan baris perintah penuh dari setiap proses yang berjalan di Windows (dieksekusi sebagai terangkat jika Anda ingin data tentang proses yang ditinggikan / admin) . Metode lain untuk melakukan ini pada Windows lebih canggung ( misalnya ).
Selanjutnya: dalam pengujian saya, cara pgrep telah menjadi satu-satunya sistem yang bekerja untuk mendapatkan path lengkap untuk skrip yang berjalan di dalam python Cygwin .

Sopalajo de Arrierez
sumber
Yang ini sebenarnya juga mencetak nama yang dapat dieksekusi asli:$ 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
Tidak berfungsi untuk saya menggunakan pgrep from procps-ng 3.3.15dan 3.3.12. Hanya mencetak nama pid dan prorgam tanpa argumen.
Socowi
4

Varian pencetakan lainnya /proc/PID/cmdline dengan spasi di Linux adalah:

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

Dengan cara ini catmencetak karakter NULL sebagai ^@dan kemudian Anda menggantinya dengan spasi menggunakan sed; echomencetak baris baru.

Diego
sumber
FYI, Anda juga bisa menggunakan cat -v / proc / PID / cmdline | sed 's / \ ^ @ / \ n / g' . Ini akan menggantikan karakter nol dengan karakter baris baru. Dengan demikian, setiap argumen akan dicetak ke barisnya sendiri. Dengan begitu, lebih mudah untuk mengatakan satu argumen dari yang lain.
TSJNachos117
2

Anda cukup menggunakan:

ps -o args= -f -p ProcessPid
Mitar
sumber
2

Daripada menggunakan banyak perintah untuk mengedit aliran, cukup gunakan satu - tr menerjemahkan satu karakter ke yang lain:

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

Selain semua cara di atas untuk mengonversi teks, jika Anda cukup menggunakan 'string', itu akan membuat output pada baris yang terpisah secara default. Dengan manfaat tambahan itu juga dapat mencegah karakter apa pun yang dapat mengacak terminal Anda muncul.

Keduanya menghasilkan dalam satu perintah:

string / proc // cmdline / proc // environment

Pertanyaan sebenarnya adalah ... apakah ada cara untuk melihat baris perintah sebenarnya dari suatu proses di Linux yang telah diubah sehingga cmdline berisi teks yang diubah dan bukan perintah sebenarnya yang dijalankan.

Timothy J. Biggs
sumber
1

Tentang Solaris

     ps -eo pid,comm

serupa dapat digunakan pada sistem seperti unix.

HuntM
sumber
1

Di Linux, dengan bash, untuk menampilkan seperti yang dikutip args sehingga Anda dapat mengedit perintah dan menjalankannya kembali

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

Di Solaris, dengan bash (diuji dengan 3.2.51 (1) -release) dan tanpa 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

Contoh Linux bash (tempel di 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
}

Keluaran:

MATCH

Contoh 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
}

Keluaran:

MATCH
Iwan Aucamp
sumber
0

Jika Anda ingin mendapatkan panjang-sebagai-mungkin (tidak yakin apa yang membatasi ada), mirip dengan Solaris' pargs , Anda dapat menggunakan ini di Linux & OSX:

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

coba ps -ndi terminal linux. Ini akan menunjukkan:

1. Semua proses MENJALANKAN , baris perintah dan PID mereka

  1. Program memulai proses.

Setelah itu Anda akan tahu proses untuk membunuh yang mana

repzero
sumber