posix kabuğu: ortam değişkeni adlarının listesini yazdır (değerler olmadan)


11

Birden çok uygulamayla çalışan posix uyumlu bir şekilde, tanımlanmış ortam değişkeni listesini değerleri olmadan nasıl yazdırabilirim ?

Bazı uygulamalarda (mksh, freebsd / bin / sh), sadece exportkendi başına kullanmak faturaya uyacaktır:

$ export
FOO2
FOO

Ancak diğer bazı uygulamalar için (bash, zsh, dash) exportde değeri gösterir. Bash ile, örneğin:

$ export
export FOO2='as  df\
  asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd  kjasdf:\
   asdkj=fkajdsf:\
       :askjfkajsf=asdfkj:\
   safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
  asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd  kjasdf:\$
   asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
   safdkj$

Gibi diğer seçenekler envveya printenvseçenekleri yok en azından değil linux ve ben denedim freebsd platformlarda, değerler olmadan sadece değişken isimlerini yazdırmak için.

Awk / sed / etc boruları. veya listeyi parametre genişletme teknikleri (örneğin ${foo%%=*}) ile kırpmak kabul edilebilir, ancak satırlara yayılabilen ve =değerde boşluk ve boşluk içeren değerlerle çalışmalıdır (yukarıdaki örneğe bakın).

Belirli kabuk uygulamalarına özgü yanıtlar ilginçtir, ancak öncelikle uygulamalar arasında uyumlu olan bir şey arıyorum.


2
Bir şeyi ayrıştıracaksanız export -p, kabuğunda giriş için de uygun çıktı üretmek üzere çıktısı POSIX tarafından belirtilenle devam edin.
Kusalananda

Bir mermiye girmek için hiçbir şeye ihtiyacım yok. Sadece ortam değişkenlerinin isimlerini istiyorum. Bu yüzden fazladan elde edilen (örneğin, her satırın önündeki 'dışa aktarma' sözcüğü) her halükarda kaldırılmalıdır. Bunun için neden kullanmak isteyeyim export -p?
Juan

1
Kullanmak istersiniz, export -pçünkü bu istediğiniz tüm POSIX mermilerinde tutarlı bir çıktı verecektir.
Kusalananda

Sadece kabukları arasında tutarlı bir çözüm olan değişken adlarını yazdıracak bir çözüm istiyorum. export -pilk gereksinime uymuyor - sadece değişken adları değersiz yazdırılıyor.
Juan

Bir şeyi ayrıştıracaksanız, çıktısını alın export -p. Bu ayrışmayı yazmayacağım, çünkü genel durumda, değeri gibi bir değişkene sahip olmanız durumunda, uygun alıntı ayrıştırma da yapmak zorunda kalacaksınız hello\nexport var=value. Biri birkaç tüm POSIX kabuklarda size tutarlı çıktı verecektir diğer komutlar olduğunu env, ama bu çıkışı zor o yoksun beri ayrıştırma için export =biraz.
Kusalananda

Yanıtlar:


9

Awk içinde oldukça kolay.

awk 'BEGIN{for(v in ENVIRON) print v}'

Ancak bazı awk uygulamalarının kendi ortam değişkenlerini eklemesine dikkat edin (örn. GNU awk ekler AWKPATHve AWKLIBPATHbuna ENVIRON).

Bir ortam değişkeninin adı, son derece alışılmadık ancak teknik olarak mümkün olan bir satırsonu içeriyorsa çıktı belirsizdir. Saf bir sh çözümü zor olurdu. En iyi seçeneğiniz başlamaktır, export -pancak saf bir şekilde masaj yapmak zordur. Çıktının masajı için sed'i kullanabilir export -p, sonra evalalıntılananı çıkarmak için kabuğu almak için kullanabilirsiniz . Bash ve zsh standart olmayan önekleri yazdırır.

report () { echo "${1%%=*}"; };
eval "$(export -p | sed "s/^export /report /;
                         s/^declare -x /report /;
                         s/typeset -x /report /")"

Kabuğa bağlı olarak, export -padı kabukta geçerli olmayan değişkenleri gösterebilir veya göstermeyebilir ve eğer değilse, o zaman adları düzgün şekilde teklif edebilir veya etmeyebilir. Örneğin, adı yeni satır, BusyBox tire ve ksh93 içeren tire, mksh ve zsh değişkenlerini çıkarır, bunları ham olarak basar ve bash değerleri olmadan ham yazdırır. Güvenilmeyen girdilere karşı savunmanız gerekiyorsa, saf bir POSIX çözümüne güvenmeyin evalve çıkışından türetilen hiçbir şeyi kesinlikle çağırmayın export -p.


Çok satırlı sed (1) ile gerçekten "kolay" olduğundan emin değilim - bunu görmek istiyorum. Ancak awk (1) yöntemi için teşekkürler. Sanırım bu şimdiye kadarki en taşınabilir yol ( exitgerekli olduğunu düşünmeme rağmen ).
Juan

Eğer alırsanız o Not FOO<newline>BAR, bunun var olup olmadığını bilmiyorum FOO<newline>BAR(ortam değişkeni export -p, en kabuklu göstermek görmeyecektir env $'FOO\nBAR=test' awk 'BEGIN{for (v in ENVIRON) print v}') ya da her ikisi de bir FOOve BARortam değişkeni.
Stéphane Chazelas

GNU awknun kendi ( AWKPATHve AWKLIBPATHsistemimdeki) ortam değişkenlerini ayarladığını unutmayın
Stéphane Chazelas

@ StéphaneChazelas - re: var adında gömülü yeni satır - kabul edildi - kabuk koduyla buna karşı savunmak zor. Re: AWKPATH & AWKLIBPATH kirliliği, ben de sinsi yerleştirme de fark ettim. Bu gnu awk, bsd awk değil.
Juan

0

Basit şeyleri severim; bu POSIX sistemleri için çalışacaktır:

printenv | sed 's;=.*;;' | sort
HOME
HOSTNAME
PATH
PWD
SHLVL
TERM

5
export AAA=$'multi\nBBB=line'
roaima

@todd_dsm - Birden fazla satıra yayılan değerlere sahip ortam değişkenleri için başarısız olur (örneğin, bazen TERMCAP - Bir ekran (1) oturumunda, IIRC) bunu görüyorum. Dolayısıyla bu cevap orijinal soruda açıklanan gereksinimleri karşılamamaktadır. Ben de basit gibi, ama bu genellikle işe yaramaz.
Juan

Orijinal yayınınızda düzenlediğiniz tidbit bash: için ilginçti compgen -e. Taşınabilir komut dizilerime yardımcı olmaz (örneğin, bash kullanılabilir olmadığında), ancak ilginçtir.
Juan

merak ediyorum, neden kendinizi bourne (posix) kabuğuyla sınırlandırıyorsunuz? posix uyumlu olmak harika ama bu arayışta çok fazla işlevsellik kaybedersiniz. taşınabilir olabilir ve bash ile posix uyumlu DEĞİLDİR; GNU ailesinin bir parçası.
todd_dsm

dashDebian kullanarak , yukarıdaki komutla aynı sonuçları printenv | sed 's;*=.;;' | sortelde veya değerleri almak için değiştirilmiş . Değişkeni dışa aktardım yove yukarıdaki ilk yorumunuzu atadım; beklendiği gibi, çoklu satırlarla yazdırılır. ne deneyimlediğinizden emin değilsiniz, ancak kesilmiş çıktı olmamalıdır. komutu kabukta çalıştır; çıktısı ne olursa olsun nasıl çalışması gerektiği; hiçbir kesim bekliyoruz. Ardından TERMCAP / screen / iirc bağlamında; aynı olmalı. Çıktı eşleşmiyorsa, bu programlardan biriyle ilgili bir sorun olabilir.
todd_dsm
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.