ฉันจะระบุตัวแปรสภาพแวดล้อมของกระบวนการอื่นได้อย่างไร


24

ถ้าฉันตรวจสอบ/proc/1/environฉันจะเห็นสตริง1สภาพแวดล้อมของกระบวนการของสตริงที่คั่นด้วย null ฉันต้องการนำตัวแปรเหล่านี้เข้าสู่สภาพแวดล้อมปัจจุบันของฉัน มีวิธีง่ายๆในการทำเช่นนี้หรือไม่?

หน้าคนให้ฉันข้อมูลโค้ดซึ่งจะช่วยให้การพิมพ์จะออกแต่ละตัวแปรสภาพแวดล้อมบนพื้นฐานบรรทัดโดยบรรทัดproc (cat /proc/1/environ; echo) | tr '\000' '\n'สิ่งนี้ช่วยฉันในการตรวจสอบเนื้อหาว่าถูกต้อง แต่สิ่งที่ฉันต้องทำจริงๆคือส่งตัวแปรเหล่านี้ไปยังเซสชัน bash ปัจจุบันของฉัน

ฉันจะทำอย่างไร

คำตอบ:


23

ต่อไปนี้จะแปลงตัวแปรสภาพแวดล้อมแต่ละตัวเป็นexportคำสั่งที่ยกมาอย่างถูกต้องสำหรับการอ่านลงในเชลล์ (เพราะLS_COLORSตัวอย่างเช่นมีแนวโน้มที่จะมีเครื่องหมายอัฒภาคอยู่) จากนั้นจึงส่งมา

[ตอนprintfใน/usr/binโชคไม่ดีโดยทั่วไปไม่สนับสนุน%qดังนั้นเราจึงจำเป็นต้องเรียกหนึ่งที่สร้างขึ้นในbash.]

. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)

ฉันแนะนำ. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)ซึ่งจะจัดการกับตัวแปรด้วยคำพูดในพวกเขาอย่างถูกต้องเช่นกัน
John Kugelman สนับสนุน Monica

ขอบคุณ @JohnKugelman มากสำหรับการปรับปรุงโดยใช้แทน"$@" '{}'สำหรับผู้ที่สงสัยเกี่ยวกับ--การโต้แย้งในคำตอบที่ดีขึ้นของเขาข้อโต้แย้งตำแหน่งที่จะbash -c command_stringมีการกำหนดราคาเริ่มต้นที่$0ในขณะที่การขยายตัวที่จะรวมถึงข้อโต้แย้งเริ่มต้นที่"$@" $1อาร์กิวเมนต์ที่ได้รับมอบหมายให้-- $0
Mark Plotnick

10

ในbashที่คุณสามารถทำได้ดังต่อไปนี้ สิ่งนี้จะทำงานสำหรับเนื้อหาที่เป็นไปได้ทั้งหมดของตัวแปรและหลีกเลี่ยงeval:

while IFS= read -rd '' var; do declare +x "$var"; done </proc/$PID/environ

สิ่งนี้จะประกาศตัวแปรอ่านเป็นตัวแปรเชลล์ในเชลล์ที่รันอยู่ หากต้องการส่งออกตัวแปรไปยังสภาพแวดล้อมเชลล์ที่กำลังทำงานอยู่ให้ทำดังนี้

while IFS= read -rd '' var; do export "$var"; done </proc/$PID/environ

10

ในคำตอบนี้ฉันถือว่าระบบที่/proc/$pid/environส่งคืนสภาพแวดล้อมของกระบวนการด้วย PID ที่ระบุพร้อมไบต์ว่างระหว่างคำจำกัดความของตัวแปร ( ดังนั้น Linux, Cygwin หรือ Solaris (?) )

zsh

export "${(@ps:\000:)$(</proc/$pid/environ)}"

(ค่อนข้างง่ายอย่างที่ zsh ไป: การเปลี่ยนทิศทางอินพุตโดยไม่มีคำสั่ง <FILEเทียบเท่าcat FILEเอาท์พุทของการทดแทนคำสั่งผ่านการขยายพารามิเตอร์ด้วยแฟล็ก ps:\000:หมายถึง "แยกบน null ไบต์" และ@ความหมาย "ถ้าสิ่งทั้งหมดอยู่ในเครื่องหมายคำพูดคู่ แต่ละองค์ประกอบของอาเรย์เป็นฟิลด์แยกต่างหาก” (โดยทั่วไป"$@")

Bash, mksh

while IFS= read -r -d "" PWD; do export "$PWD"; done </proc/$pid/environ
PWD=$(pwd)

(ในเปลือกหอยเหล่านี้เป็นตัวคั่นว่างส่งผ่านไปยังreadผลลัพธ์ใน null ไบต์เป็นตัวคั่น. ผมใช้PWDเป็นชื่อตัวแปรชั่วคราวเพื่อหลีกเลี่ยงการ clobbering ตัวแปรที่อาจจะจบลงด้วยการถูกนำเข้ามาอีก. ในขณะที่คุณได้ในทางเทคนิคสามารถนำเข้าPWDได้เป็นอย่างดีก็จะเพียงพักวางจนกว่า ถัดไปcd)

POSIX

การพกพา POSIX นั้นไม่น่าสนใจสำหรับคำถามนี้เพราะมันใช้ได้กับระบบที่มี/proc/PID/environเท่านั้น ดังนั้นคำถามคือสิ่งที่สนับสนุน Solaris - หรือว่ามี Solaris /proc/PID/environมันไม่ได้ใช้ แต่ฉันไปทางโค้งบนคุณสมบัติ Solaris ดังนั้นปัจจุบันอาจ บน Linux ยูทิลิตี้ GNU และ BusyBox มีทั้งความปลอดภัย แต่มี Caveates

หากเรายืนยันในการพกพา POSIX ไม่จำเป็นต้องใช้ยูทิลิตีข้อความ POSIX ในการจัดการไบต์ว่างดังนั้นจึงเป็นเรื่องยาก นี่คือวิธีแก้ปัญหาที่สมมติว่า awk สนับสนุนไบต์ที่ว่างเป็นตัวคั่นเร็กคอร์ด (nawk and gawk ทำเช่นเดียวกับ BusyBox awk แต่ mawk ไม่ได้)

eval $(</proc/$pid/environ awk -v RS='\0' '{gsub("\047", "\047\\\047\047"); print "export \047" $0 "\047"}')

BusyBox awk (ซึ่งเป็นรุ่นที่พบได้ทั่วไปบนระบบลินุกซ์ฝังตัว) ไม่สนับสนุน null ไบต์ แต่ไม่ตั้งค่าRSไป"\0"ในBEGINบล็อกและไม่คำสั่งไวยากรณ์บรรทัดข้างต้น -v 'RS="\0"'แต่ก็ไม่สนับสนุน ฉันไม่ได้ตรวจสอบสาเหตุว่าทำไมนี่เป็นข้อผิดพลาดในรุ่นของฉัน (Debian wheezy)

(ตัดทุกบรรทัดระเบียนที่คั่นด้วย null ในเครื่องหมายคำพูดเดี่ยว"\047"หลังจากหนีเครื่องหมายอัญประกาศเดี่ยวภายในค่า)

คำเตือน

ระวังว่าสิ่งเหล่านี้อาจพยายามตั้งค่าตัวแปรแบบอ่านอย่างเดียว (ถ้าเชลล์ของคุณมีตัวแปรแบบอ่านอย่างเดียว)


ในที่สุดฉันก็กลับมาที่นี่ ฉันคิดหาวิธีที่ไม่น่าเชื่อถือในการทำสิ่งนี้หรือการจัดการใด ๆ ในกระสุนทั้งหมดที่ฉันรู้เกี่ยวกับสวย ๆ ดูคำตอบใหม่ของฉัน
mikeserv

6

ฉันไปรอบ ๆ ด้วยสิ่งนี้ ฉันรู้สึกหงุดหงิดกับการพกพาแบบ null bytes ฉันนั่งไม่ดีกับฉันว่าไม่มีวิธีที่เชื่อถือได้ในการจัดการพวกเขาในเปลือก ดังนั้นฉันจึงดูต่อไป ความจริงก็คือฉันพบหลายวิธีในการทำเช่นนี้มีเพียงไม่กี่ข้อเท่านั้นที่ถูกบันทึกไว้ในคำตอบอื่น ๆ ของฉัน แต่ผลลัพธ์มีฟังก์ชันเชลล์อย่างน้อยสองฟังก์ชันที่ทำงานดังนี้:

_pidenv ${psrc=$$} ; _zedlmt <$near_any_type_of_file

ก่อนอื่นฉันจะพูดเกี่ยวกับการ\0กำหนด อันที่จริงมันค่อนข้างง่ายที่จะทำ นี่คือฟังก์ชั่น:

_zedlmt() { od -t x1 -w1 -v  | sed -n '
    /.* \(..\)$/s//\1/
    /00/!{H;b};s///
    x;s/\n/\\x/gp;x;h'
}

เป็นพื้น odจะใช้เวลาstdinและเขียนไปยังstdoutแต่ละไบต์ที่ได้รับเป็นเลขฐานสิบหกต่อหนึ่งบรรทัด

printf 'This\0is\0a\0lot\0\of\0\nulls.' |
    od -t x1 -w1 -v
    #output
0000000 54
0000001 68
0000002 69
0000003 73
0000004 00
0000005 69
0000006 73
    #and so on

ฉันพนันได้เลยว่าคุณเดาได้ว่าอัน\0nullไหนใช่ไหม? เขียนออกมาเช่นว่ามันจัดการง่าย sedด้วยsedเพียงบันทึกสองตัวอักษรสุดท้ายในแต่ละบรรทัดจนกว่าจะพบค่าว่าง ณ จุดที่มันแทนที่บรรทัดใหม่กลางด้วยprintfรหัสรูปแบบที่เป็นมิตรและพิมพ์สตริง ผลลัพธ์ที่ได้คือ\0nullอาเรย์ที่คั่นด้วยสตริงสตริง hex ดู:

printf %b\\n $(printf 'Fewer\0nulls\0here\0.' |
    _zedlmt | tee /dev/stderr)
    #output
\x46\x65\x77\x65\x72
\x6e\x75\x6c\x6c\x73
\x68\x65\x72\x65
\x2e
Fewer
nulls
here
.

ฉันส่งไปด้านบนเพื่อteeให้คุณสามารถดูทั้งผลลัพธ์ของคำสั่ง susbstitution และผลลัพธ์ของprintfการประมวลผล ฉันหวังว่าคุณจะสังเกตเห็นว่าจริง ๆ แล้วการแยกชั้นย่อยไม่ได้ยกมา แต่printfยังแยกเพียงที่\0nullตัวคั่นเท่านั้น ดู:

printf %b\\n $(printf \
        "Fe\n\"w\"er\0'nu\t'll\\'s\0h    ere\0." |
_zedlmt | tee /dev/stderr)
    #output
\x46\x65\x0a\x22\x77\x22\x65\x72
\x27\x6e\x75\x09\x27\x6c\x6c\x27\x73
\x68\x20\x20\x20\x20\x65\x72\x65
\x2e
Fe
"w"er
'nu     'll's
h    ere
.

ไม่มีคำพูดในการขยายตัวเช่นกัน - มันไม่สำคัญว่าคุณจะพูดหรือไม่ นี่เป็นเพราะค่าการกัดนั้นผ่านมาไม่ได้แยกออกจากกันยกเว้นค่าการกัด\n ewline ที่สร้างขึ้นในแต่ละครั้งที่sedพิมพ์สตริง การแยกคำไม่ได้ใช้ และนั่นคือสิ่งที่ทำให้สิ่งนี้เป็นไปได้:

_pidenv() { ps -p $1 >/dev/null 2>&1 &&
        [ -z "${1#"$psrc"}" ] && . /dev/fd/3 ||
        cat <&3 ; unset psrc pcat
} 3<<STATE
        $( [ -z "${1#${pcat=$psrc}}" ] &&
        pcat='$(printf %%b "%s")' || pcat="%b"
        xeq="$(printf '\\x%x' "'=")"
        for x in $( _zedlmt </proc/$1/environ ) ; do
        printf "%b=$pcat\n" "${x%%"$xeq"*}" "${x#*"$xeq"}"
        done)
#END
STATE

ฟังก์ชั่นด้านบนใช้_zedlmtกับ${pcat}สตรีมโค้ดไบต์ที่เตรียมไว้สำหรับการจัดหาสภาพแวดล้อมของกระบวนการใด ๆ ที่สามารถพบได้ใน/procหรือโดยตรง.dot ${psrc}ในเชลล์ปัจจุบันโดยตรงหรือโดยไม่มีพารามิเตอร์เพื่อแสดงเอาต์พุตที่ประมวลผลเหมือนกับเทอร์มินัลเช่นsetหรือprintenvจะ สิ่งที่คุณต้องมีคือ$pid- ไฟล์ใด ๆ ที่อ่านได้/proc/$pid/environจะทำ

คุณใช้มันแบบนี้:

#output like printenv for any running process
_pidenv $pid 

#save human friendly env file
_pidenv $pid >/preparsed/env/file 

#save unparsed file for sourcing at any time
_pidenv ${pcat=$pid} >/sourcable/env.save 

#.dot source any pid's $env from any file stream    
_pidenv ${pcat=$pid} | sh -c '. /dev/stdin'

#feed any pid's env in on a heredoc filedescriptor
su -c '. /dev/fd/4' 4<<ENV
    $( _pidenv ${pcat=$pid} )
ENV

#.dot sources any $pid's $env in the current shell
_pidenv ${psrc=$pid} 

แต่อะไรคือความแตกต่างระหว่างความเป็นมิตรของมนุษย์และการหาที่มา ? ความแตกต่างคือสิ่งที่ทำให้คำตอบนี้แตกต่างจากที่อื่น - รวมถึงคำตอบของฉันด้วย ทุกคำตอบอื่น ๆ ขึ้นอยู่กับการอ้างถึงเชลล์ในทางใดทางหนึ่งเพื่อจัดการกับกรณีขอบทั้งหมด มันใช้งานได้ไม่ดี โปรดเชื่อฉัน - ฉันลองดู:

_pidenv ${pcat=$$}
    #output
LC_COLLATE=$(printf %b "\x43")
GREP_COLOR=$(printf %b "\x33\x37\x3b\x34\x35")
GREP_OPTIONS=$(printf %b "\x2d\x2d\x63\x6f\x6c\x6f\x72\x3d\x61\x75\x74\x6f")
LESS_TERMCAP_mb=$(printf %b "\x1b\x5b\x30\x31\x3b\x33\x31\x6d")
LESS_TERMCAP_md=$(printf %b "\x1b\x5b\x30\x31\x3b\x33\x31\x6d")
LESS_TERMCAP_me=$(printf %b "\x1b\x5b\x30\x6d")
LESS_TERMCAP_se=$(printf %b "\x1b\x5b\x30\x6d")
LESS_TERMCAP_so=$(printf %b "\x1b\x5b\x30\x30\x3b\x34\x37\x3b\x33\x30\x6d")
LESS_TERMCAP_ue=$(printf %b "\x1b\x5b\x30\x6d")

NOจำนวนตัวอักษรขี้ขลาดหรือมีอยู่ quoting สามารถทำลายนี้เพราะไบต์สำหรับแต่ละค่าไม่ได้ประเมินจนมากทันทีเนื้อหามีที่มา และเรารู้อยู่แล้วว่ามันทำงานเป็นค่าอย่างน้อยหนึ่งครั้ง - ไม่มีการแยกวิเคราะห์หรืออ้างจำเป็นที่นี่เพราะนี่เป็นสำเนาไบต์ต่อไบต์ของค่าเดิม

ฟังก์ชันจะประเมิน$varชื่อและรอการตรวจสอบให้เสร็จก่อนที่จะ.dotจัดหา here-doc ที่ป้อนเข้ามาใน file-descriptor 3 ก่อนที่มันจะมามันเป็นสิ่งที่ดูเหมือน มันโง่เขลา และ POSIX แบบพกพา อย่างน้อยที่สุด \ 0 การจัดการที่ว่างเปล่าเป็น POSIX แบบพกพา - ระบบไฟล์ / กระบวนการนั้นมีความเฉพาะของ Linux และนั่นเป็นเหตุผลที่มีสองฟังก์ชั่น


3

การใช้sourceและการทดแทนกระบวนการ :

source <(sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ)

ไม่นาน:

. <(sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ)

การใช้evalและการทดแทนคำสั่ง :

eval `sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ`

การsedโทรสามารถถูกแทนที่ด้วยการawkโทร:

awk -vRS='\x00' '{ print "export", $0 }' /proc/1/environ

แต่อย่าลืมว่าจะไม่ล้างตัวแปรสภาพแวดล้อมใด ๆ ที่ไม่ได้อยู่ใน pid 1


การส่งออกซ้ำซ้อนเป็นคำตอบของ @ fr00tyl00p หรือไม่ เพราะถ้าไม่ดูเหมือนว่ามันสำคัญมาก
Dane O'Connor

ใช่จำเป็นต้องส่งออก ฉันจะแก้ไขมัน
Pavel Šimerda

3
คำสั่งเหล่านี้ทั้งหมดสำลักค่าที่มีบรรทัดใหม่และ (ขึ้นอยู่กับคำสั่ง) อักขระอื่น ๆ
Gilles 'หยุดชั่วร้าย'

แก้ไข. จะเก็บคำตอบไว้เพื่ออ้างอิงต่อไป
Pavel Šimerda

3

เป็นที่น่าสังเกตว่ากระบวนการสามารถมีตัวแปรสภาพแวดล้อมที่ไม่ถูกต้องตัวแปร Bash / Sh / * sh - POSIX แนะนำ แต่ไม่ต้องการให้ตัวแปรสภาพแวดล้อมมีชื่อที่ตรงกัน ^[a-zA-Z0-9_][a-zA-Z0-9_]*$แต่ไม่จำเป็นต้องว่าตัวแปรสภาพแวดล้อมที่มีชื่อการจับคู่

เพื่อสร้างรายการของตัวแปรที่เชลล์เข้ากันได้กับสภาพแวดล้อมของกระบวนการอื่นใน Bash:

function env_from_proc {
  local pid="$1" skipped=( )
  cat /proc/"$pid"/environ | while read -r -d "" record
  do
    if [[ $record =~ ^[a-zA-Z_][a-zA-Z0-9_]*= ]]
    then printf "export %q\n" "$record"
    else skipped+=( "$record" )
    fi
  done
  echo "Skipped non-shell-compatible vars: ${skipped[@]%%=*}" >&2
}

ในทำนองเดียวกันในการโหลด:

function env_from_proc {
  local pid="$1" skipped=( )
  while read -r -d "" record
  do
    if [[ $record =~ ^[a-zA-Z_][a-zA-Z0-9_]*= ]]
    then export "$(printf %q "$record")"
    else skipped+=( "$record" )
    fi
  done < /proc/"$pid"/environ
  echo "Skipped non-shell-compatible vars: ${skipped[@]%%=*}" >&2
}

ปัญหานี้เกิดขึ้นเพียงบางครั้ง แต่เมื่อมัน ...


0

ฉันคิดว่านี่เป็น POSIX แบบพกพา:

. <<ENV /dev/stdin
    $(sed -n 'H;${x;s/\(^\|\x00\)\([^=]*.\)\([^\x00]*\)/\2\x27\3\x27\n/gp}' \
       /proc/$pid/environ)
ENV

แต่ @Gilles ทำให้เป็นจุดที่ดี - sedอาจจะจัดการกับโมฆะ แต่อาจจะไม่ ดังนั้นจึงมี(ฉันคิดว่าดังนั้นในเวลานี้)จริง ๆ แล้ววิธีการพกพา POSIX เช่นกัน:

s=$$SED$$
sed 's/'\''/'$s'/;1s/^./'\''&/' </proc/"$$"/environ |
tr '\0' "'" |
sed 's/'\''/&\n&/g' |
sed '1d;$d;s/^\('\''\)\([^=]*.\)/\2\1/;s/'$s'/'\\\''/g'

ถึงกระนั้นหากคุณมี GNU sedคุณต้องทำ:

sed -z 's/^[^=]*./&'\''/;s/$/'\''\n/' </proc/"$$"/environ

  #BOTH METHODS OUTPUT:

ป้อนคำอธิบายรูปภาพที่นี่

ดี POSIX พกพาที่ยกเว้นสำหรับ /dev/...ที่ไม่ได้ระบุไว้ แต่คุณสามารถคาดหวังว่าไวยากรณ์จะทำงานเหมือนกันใน Unices ส่วนใหญ่

ตอนนี้ถ้าสิ่งนี้เกี่ยวข้องกับคำถามอื่นของคุณคุณอาจต้องการใช้มันในลักษณะนี้:

nsenter -m -u -i -n -p -t $PID /bin/bash 5<<ENV --rcfile=/dev/fd/5 
    $(sed -z 's/^[^=]*./&'\''/;s/$/'\''\n/' </proc/"$$"/environ)
ENV

ที่นี่-doc เป็นประโยชน์อย่างมากในการที่จะช่วยให้เปลือกจากการกวดขันกับใด ๆ ของข้อความที่เราทำงานอย่างหนักเพื่อที่จะจัดการใน subshell และยังช่วยให้เราเป็นเส้นทางที่มีความน่าเชื่อถือให้กับ.dotsourceable ไฟล์มากกว่าอีกครั้ง subshell หรือเปลือก ตัวแปร. คนอื่น ๆ ที่นี่ใช้<(process substitution)bashism ซึ่งทำงานในลักษณะเดียวกัน - เฉพาะแน่นอนว่าไม่ระบุตัวตน|pipeในขณะที่ POSIX จะระบุเฉพาะiohereเอกสารที่นี่เท่านั้นและเพื่อให้สามารถเป็นไฟล์ประเภทใดก็ได้ในทางปฏิบัติแล้วมักจะเป็นtempไฟล์ ( dash,บนมืออื่น ๆ ที่ไม่ใช้ที่ไม่ระบุชื่อ|pipesสำหรับที่นี่เอกสาร) อัปมงคลเกี่ยวกับกระบวนการทดแทน แต่เป็นก็ยังขึ้นอยู่กับเปลือก - initซึ่งอาจจะเป็นปัญหาที่น่ารำคาญโดยเฉพาะอย่างยิ่งถ้าคุณทำงานอยู่กับ

นอกจากนี้ยังใช้งานได้กับ|pipesแน่นอน แต่แล้วคุณจะสูญเสียสภาพแวดล้อมอีกครั้งในตอนท้ายเมื่อ|pipe'sรัฐระเหยด้วย subshell จากนั้นอีกครั้งใช้งานได้:

sed '...;a\exec <>/dev/tty' /proc/$pid/environ | sh -i 

sedคำสั่งตัวเองทำงานโดยถือสายในหน่วยความจำจนกว่าจะถึงสุดท้ายทุกเวลาที่จะดำเนินการทั่วโลกแทนที่จัดการ quoting และการแทรกการขึ้นบรรทัดใหม่ที่เหมาะสมโดยยึดบน nulls ค่อนข้างเรียบง่ายจริงๆ

ในdashภาพคุณจะเห็นฉันเลือกที่จะหลบหนี \ ระเบียบและเพิ่มGNUเฉพาะเจาะจงตัวเลือกในการ-r sedแต่นั่นเป็นเพียงสาเหตุที่ทำให้พิมพ์น้อยลง มันทำงานได้ทั้งสองวิธีตามที่คุณเห็นในzshภาพ

ที่นี่zsh:

ป้อนคำอธิบายรูปภาพที่นี่

และนี่คือdashการทำสิ่งเดียวกัน:

ป้อนคำอธิบายรูปภาพที่นี่

แม้กระทั่งการหลบหนีออกจากอาคารผ่านพ้นอันตราย:

ป้อนคำอธิบายรูปภาพที่นี่


นี่ไม่ใช่แบบพกพา POSIX เพราะไม่จำเป็นต้องใช้ sed เพื่อจัดการกับ null null (ที่ถูกกล่าวว่า, POSIX พกพาไม่ได้เป็นที่น่าสนใจสำหรับคำถามนี้เพราะมันจะใช้กับระบบที่มี/proc/PID/environดังนั้นคำถามคือสิ่งที่ Solaris sed สนับสนุน -. หรือไม่ว่า Solaris มี/proc/PID/environก็ไม่ได้ใช้ แต่ฉันวิธี เบื้องหลังโค้งของคุณสมบัติของ Solaris ดังนั้นทุกวันนี้อาจจะมี)
Gilles 'SO- หยุดความชั่วร้าย'

@ หมายเลข Gilles แต่sedจำเป็นต้องมีการจัดการเลขฐานสิบหกแบบ ascii ซึ่งค่า null เป็นหนึ่ง นอกจากนี้ฉันแค่คิดว่าถ้ายังทำวิธีนี้ได้ง่ายขึ้น
mikeserv

ไม่ POSIX บอกว่า“ ไฟล์อินพุตจะเป็นไฟล์ข้อความ” (สำหรับ sed และโปรแกรมอรรถประโยชน์ข้อความอื่น ๆ ) และกำหนดไฟล์ข้อความเป็น“ ไฟล์ที่มีอักขระที่จัดเป็นหนึ่งบรรทัดหรือมากกว่า บรรทัดไม่มีอักขระ NUL (…)” และโดยวิธีการที่\xNNไม่จำเป็นต้องใช้ไวยากรณ์ใน POSIX ไม่แม้แต่\OOOไวยากรณ์ฐานแปด (ในสตริง C และใน awk ใช่ แต่ไม่ใช่ใน regexps sed)
Gilles 'หยุดความชั่วร้าย'

@Gilles คุณมีจุด ฉันมองไปทั่วและไม่พบสิ่งที่ฉันคิดว่าทำได้ก่อนหน้านี้ ดังนั้นฉันจึงทำมันแตกต่างกัน กำลังแก้ไขในขณะนี้
mikeserv

เท่าที่ฉันสามารถบอกได้ Solaris ไม่ได้มี/proc/PID/environ(มันมีหลายรายการเหมือน Linux อื่น ๆ/proc/PIDแต่ไม่environ) ดังนั้นโซลูชันแบบพกพาไม่จำเป็นต้องไปไกลเกินกว่าเครื่องมือของลีนุกซ์หมายความว่า GNU sed หรือ BusyBox sed ทั้งสองรองรับ\x00ใน regexp ดังนั้นรหัสของคุณสามารถพกพาได้ตามต้องการ (แต่ไม่ใช่ POSIX) มันซับซ้อนเกินไป
Gilles 'หยุดความชั่วร้าย'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.