Bununla gittim ve etrafa döndüm. Boş baytların taşınabilirliği konusunda sinirliydim. Benimle iyi oturmuyor, onları bir kabukta kullanmanın güvenilir bir yolu yoktu. Ben de bakmaya devam ettim. Gerçek şu ki, bunu yapmanın birkaç yolunu buldum, sadece birkaçını diğer cevabımda belirtmiştim. Ancak sonuçlar şöyle çalışan en az iki kabuk işlevi idi:
_pidenv ${psrc=$$} ; _zedlmt <$near_any_type_of_file
İlk önce \0
sınırlandırma hakkında konuşacağım . Aslında yapmak oldukça kolaydır. İşte fonksiyon:
_zedlmt() { od -t x1 -w1 -v | sed -n '
/.* \(..\)$/s//\1/
/00/!{H;b};s///
x;s/\n/\\x/gp;x;h'
}
Temel olarak, her satır onaltılık olarak aldığı her bayt od
alır stdin
ve yazar 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
Bahse girerim hangisi olduğunu tahmin edebilirsin \0null
, değil mi? Bu şekilde yazılmış herhangi biriyle başa çıkmak kolaydır sed
. sed
sadece her iki satırdaki son iki karakteri kaydeder, bu noktada ortadaki yeni satırları printf
dostça format koduyla değiştirir ve dizeyi yazdırır. Sonuç, \0null
ayrılmış bir onaltılık bayt dizisi dizisidir. Bak:
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
.
Yukarıdakileri tee
yayınladım , böylece hem suslama emri çıktısını hem de işlemin sonucunu görebilirsiniz printf
. Umarım alt kabuğun aslında kote olmadığını ama printf
hala \0null
sınırlayıcıda ayrıldığını farkedersiniz . Bak:
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
.
Bu genişlemeden hiçbir alıntı yok; alıntı yapıp yapmamanız önemli değil. Bunun nedeni, ısırık değerlerinin \n
, her zaman sed
bir dize basması için oluşturulan bir ewline hariç, ayrılmamış olarak gelmesidir . Sözcük bölme geçerli değildir. Ve bunu mümkün kılan şey bu:
_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
Yukarıdaki fonksiyon kullanımları _zedlmt
birine ${pcat}
bulunabilir herhangi bir işlem ortam kaynak için bayt kod hazırlanmış bir akımı /proc
ya da doğrudan .dot
${psrc}
, mevcut kabuk aynı ya da bir parametre olmadan gibi uç aynı işlenmiş bir görüntü çıkışı set
ya da printenv
olacak. Tek ihtiyacınız olan bir $pid
- okunabilir herhangi bir/proc/$pid/environ
dosya yapacak.
Bunu böyle kullanıyorsun:
#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}
Ama insan dostu ve kaynaklanabilir arasındaki fark nedir ? Aradaki fark, bu cevabı burada diğerlerinden farklı kılan şeydir - benim diğerini de dahil. Diğer tüm cevaplar, tüm kenar davalarını ele almak için kabuğun bir şekilde veya başka bir şekilde alıntı yapmasına bağlıdır. Sadece o kadar iyi çalışmıyor. Lütfen bana inan - ben TRIED ettik Bak:
_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")
HAYIR miktarda funky karakter veya içerilen alıntı bu içerikten kaynaklanana kadar her değer için bayt değerlendirilmediğinden bunu bozabilir. Ve biz zaten en az bir kere bir değer olarak çalıştığını biliyoruz - burada ayrıştırma veya fiyat teklifi koruması gerekmiyor çünkü bu orijinal değerin bayt bayt kopyası.
Bu işlev ilk önce $var
isimleri değerlendirir ve .dot
burada dosya-tanımlayıcı 3'e beslenen here-doc kaynağını almadan önce kontrollerin tamamlanmasını bekler. Kaynaklanmadan önce göründüğü gibi. Bu aptal kanıtı. Ve POSIX taşınabilir. Eh, en azından \ 0null işleme POSIX taşınabilirdir - / process dosya sistemi açıkça Linux'a özgüdür. İşte bu yüzden iki fonksiyon var.
. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)
düzgün yanı onları tırnak değişkenleri idare edecek olan.