บน SunOS มีpargs
คำสั่งที่พิมพ์อาร์กิวเมนต์บรรทัดคำสั่งที่ส่งไปยังกระบวนการทำงาน
มีคำสั่งที่คล้ายกันในสภาพแวดล้อม Unix อื่น ๆ หรือไม่?
บน SunOS มีpargs
คำสั่งที่พิมพ์อาร์กิวเมนต์บรรทัดคำสั่งที่ส่งไปยังกระบวนการทำงาน
มีคำสั่งที่คล้ายกันในสภาพแวดล้อม Unix อื่น ๆ หรือไม่?
คำตอบ:
มีหลายตัวเลือก:
ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo
มีข้อมูลเพิ่มเติมใน/proc/<pid>
Linux เพียงแค่ดู
สิ่งอื่น ๆ ที่ Unixes อาจแตกต่างกัน ps
คำสั่งจะทำงานได้ทุกที่ที่/proc
สิ่งที่เป็นระบบปฏิบัติการที่เฉพาะเจาะจง ยกตัวอย่างเช่นบน AIX ไม่มีในcmdline
/proc
ps -ww -fp <pid>
) เพื่อระบุเอาต์พุตแบบกว้างเนื่องจากหากมีคำสั่งหลายคำสั่งก็จะถูกตัดออก
-ww
ตัวเลือกที่ช่วยให้สามารถเข้าถึงอาร์กิวเมนต์บรรทัดคำสั่งเต็มรูปแบบ (เท่าที่จะถูกเก็บไว้โดย kernel) ดูเพิ่มเติม: วิธี Solaris และ BSD รับพารามิเตอร์ commandline untruncated สำหรับกระบวนการและPS ตัวเลือก
cat /proc/<pid>/cmdline
ใช้ได้กับ Cygwin โดยที่อาร์กิวเมนต์บรรทัด cmd ไม่แสดงps
พร้อมกับตัวเลือกใด ๆ
args
เท่านั้นคำสั่งคือps -o args -p <pid>
และจะพิมพ์args
หรือใช้ -o cmd
หากคุณต้องการดูcmd
เท่านั้น การพยายามอ่าน/proc/<pid>/cmdline
จะไม่สามารถใช้ได้กับผู้ใช้ที่ด้อยโอกาสเสมอไป ps
ยูทิลิตี้จะทำงาน
/proc/<pid>/cmdline
ถูก จำกัด (ฮาร์ดโค้ดเป็นค่าของพารามิเตอร์เคอร์เนล PAGE_SIZE) ดังนั้นบรรทัดคำสั่งที่ยาวกว่าจะยังคงถูกตัดทอน! ดูstackoverflow.com/questions/199130/…สำหรับข้อมูลเพิ่มเติม คุณสามารถสอบถามการตั้งค่าเคอร์เนลของคุณด้วยgetconf PAGE_SIZE
โดยปกติแล้วคือ 4096
นี่จะเป็นการหลอกลวง:
xargs -0 < /proc/<pid>/cmdline
หากไม่มี xargs จะไม่มีช่องว่างระหว่างอาร์กิวเมนต์เนื่องจากถูกแปลงเป็น NUL
xargs -0 < /proc/<pid>/cmdline
ได้
สำหรับระบบ 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
รับคือคุณ commandline ของกระบวนการ (รวมถึง args) แต่ด้วย whitespaces ทั้งหมดเปลี่ยนเป็นอักขระ NUL
คุณสามารถใช้pgrep
กับ-f
(บรรทัดคำสั่งเต็ม) และ-l
(คำอธิบายแบบยาว):
pgrep -l -f PatternOfProcess
วิธีนี้มีความแตกต่างที่สำคัญกับการตอบสนองอื่น ๆ : มันทำงานบนCygWinดังนั้นคุณสามารถใช้มันเพื่อรับบรรทัดคำสั่งทั้งหมดของกระบวนการใด ๆ ที่ทำงานภายใต้ Windows (ดำเนินการในระดับที่สูงขึ้นหากคุณต้องการข้อมูลเกี่ยวกับกระบวนการยกระดับ / ผู้ดูแลระบบ) . วิธีอื่นใดสำหรับการทำเช่นนี้บน Windows นั้นน่าอึดอัดใจมากกว่า ( ตัวอย่าง )
นอกจากนี้ในการทดสอบของฉันวิธี pgrep ได้รับเพียงระบบเดียวที่ทำงานเพื่อให้ได้เส้นทางที่เต็มรูปแบบสำหรับสคริปต์การทำงานภายในของงูหลาม Cygwin
$ exec -a fakename bash & [1] 14102 [1]+ Stopped exec -a fakename bash $ xargs -0 < /proc/14102/cmdline; fakename $ pgrep -l -f fakename; 14102 bash
pgrep from procps-ng 3.3.15
3.3.12
เพียงพิมพ์ชื่อ pid และ prorgam โดยไม่มีข้อโต้แย้ง
ตัวแปรอื่นของการพิมพ์/proc/PID/cmdline
พร้อมช่องว่างใน Linux คือ:
cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo
ด้วยวิธีนี้cat
พิมพ์อักขระ NULLเป็น^@
และจากนั้นคุณแทนที่ด้วยช่องว่างโดยใช้sed
; echo
พิมพ์บรรทัดใหม่
คุณสามารถใช้:
ps -o args= -f -p ProcessPid
แทนที่จะใช้คำสั่งหลายคำสั่งเพื่อแก้ไขกระแสข้อมูลเพียงใช้คำสั่งหนึ่ง - tr แปลอักขระหนึ่งตัวเป็นอีกตัวหนึ่ง:
tr '\0' ' ' </proc/<pid>/cmdline
นอกจากวิธีข้างต้นทั้งหมดในการแปลงข้อความหากคุณใช้ 'strings' มันจะสร้างผลลัพธ์เป็นบรรทัดแยกตามค่าเริ่มต้น ด้วยสิทธิประโยชน์เพิ่มเติมที่อาจป้องกันไม่ให้ตัวอักษรใด ๆ ที่อาจเบียดเทอร์มินัลของคุณไม่ให้ปรากฏ
เอาต์พุตทั้งสองในหนึ่งคำสั่ง:
strings / proc // cmdline / proc // environ
คำถามจริงคือ ... มีวิธีดูบรรทัดคำสั่งจริงของกระบวนการใน Linux ที่มีการเปลี่ยนแปลงเพื่อให้ cmdline มีข้อความที่เปลี่ยนแปลงแทนคำสั่งจริงที่ถูกเรียกใช้
บนโซลาริส
ps -eo pid,comm
คล้ายกันสามารถใช้กับระบบยูนิกซ์เช่น
บน Linux ด้วย bash เพื่อส่งออกเป็น args ที่ยกมาเพื่อให้คุณสามารถแก้ไขคำสั่งและรันซ้ำได้
</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
bash -c 'printf "%q " "${1}"' /dev/null; echo
บน Solaris ด้วย bash (ทดสอบด้วย 3.2.51 (1) - ปล่อย) และไม่มี 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
ตัวอย่าง bash Linux (วางใน 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
}
เอาท์พุท:
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 pargs ของคุณสามารถใช้สิ่งนี้บน Linux & OSX:
ps -ww -o pid,command [-p <pid> ... ]
ลอง ps -n
ใน terminal linux สิ่งนี้จะแสดง:
1. กระบวนการทั้งหมดรันบรรทัดคำสั่งและPIDของพวกเขา
หลังจากนั้นคุณจะรู้ว่ากระบวนการใดที่จะฆ่า
tr \\0 ' ' < /proc/<pid>/cmdline