İçinde nokta (.) Bulunan bir değişkeni dışa aktarma


38

İçinde nokta olan bir değişkeni dışa aktarma. Denedim 'geçersiz değişken adı' alıyorum:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Hatta kaçan meta karakter nokta (.) Bile yardım etmedi.

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier


1
maalesef benzer bir soru yazdığımda / aradığımda listelenmiyor. üzgünüm. ..
user1587504

Yanıtlar:


49

En azından bashman sayfası için verme sözdizimini şu şekilde tanımlar:

export [-fn] [name[=word]] ...

Aynı zamanda bir "isim" olarak tanımlar:

   name   A  word  consisting  only  of alphanumeric characters and under
          scores, and beginning with an alphabetic character or an  under
          score.  Also referred to as an identifier.

Bu nedenle my.home, geçerli bir tanımlayıcı olmadığı gibi bir değişkeni tanımlayamazsınız.

Ksh'nizin bir tanımlayıcıya çok benzer bir tanımı olduğundan ve bu yüzden bu tür değişkenlere izin vermediğinden eminim. (Man sayfasına bakınız.)

Ayrıca, tanımlayıcı olarak neye izin verildiğini (ve dolayısıyla değişken bir ad) belirten bir tür genel standart (POSIX?) Olduğundan da çok eminim.


Bir nedenden dolayı bu tür bir değişkene gerçekten ihtiyacınız varsa, bunun gibi bir şey kullanabilirsiniz.

env "my.home=/tmp/someDir" bash

Yine de tanımlamak için. Fakat yine de normal kabuk sözdizimini kullanarak buna erişemezsiniz. Bu durumda muhtemelen perl gibi başka bir dile ihtiyacınız vardır:

perl -e 'print $ENV{"my.home"}'

Örneğin

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

yolunu basmalısın.


Karınca entegrasyonu nedeniyle. Ve ne yazık ki unix'ten değişken ayarlamaya / dışa aktarmaya izin vermiyor. Cevabınızı kabul ediyorum. ..
user1587504

1
ant, genellikle ANT_OPTSveya ~ / .antrc adında tek bir ortam değişkeni ile yapılandırılır . Karınca kendisi için garip ortam değişken isimlerine gerek yok.
michas

8

Ortam değişkenleri, eşittir işareti veya boş bayt içermeyen herhangi bir ada sahip olabilir (boş dize dahil), harita ortamı değişkenlerini kabuk değişkenlerine kabuklar ve çoğu kabukta, değişken adları ASCII alfanümerik karakterlerle ve _ilk karakterin yapılabileceği yerlerle sınırlıdır. t bir rakam olması (konumsal parametreler ve benzeri diğer özel olanlar hariç $*, $-, $@, ..., (ilgili ortam değişkenleri eşlenen edilmeyen)). Ayrıca bazı değişkenlerin kabuk tarafından / özel tarafından ayrıldığını unutmayın .

Bunun istisnaları:

  • rcKabuk ve benzeri türevleri esve akangaboş dize dışında herhangi bir ad desteklemek ve tüm sayısal veya ihtiva edenler =karakterleri (her zaman ve çevre için tüm değişkenleri ihracat ve özel değişkenlerin dikkat ister *, status, pid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;
    

    Bununla birlikte, adı kod içermeyen değişkenler için veya yürütülen komutlar ortamında geçirildiğinde diziler için kendi kodlamasını kullanır:

    $ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
    __2b=zzz$
    __5f_=zzz$
    a=zzz\001xxx$
    $ env +=x rc -c "echo $'+'"
    x
    $ env __2b=x rc -c "echo $'+'"
    x
    
  • AT & T ksh, yashve zsh(aynı zamanda bashama sadece tek bayt karakterler için) geçerli yerele değil, yalnızca ASCII olanlar destek alnums.

    $ Stéphane=1
    $ echo "$Stéphane"
    1
    

    Bu kabuklarda, çoğu karakteri alfa olarak kabul etmek için yerel ayarları değiştirebilirsiniz, ancak yine de ASCII karakterleri için işe yaramaz .. Kandırmak zshya kshda düşünmek £bir mektuptur, ama o .ya da başka bir ASCII karakterini değil (değişken isimlerindeki karakterlere izin vermek, [[:alpha:]]örneğin dünya için değil ).

  • ksh93adı gibi bir nokta içeren özel değişkenlere sahip ${.sh.version}, ancak bunlar çevre değişkenleriyle eşlenmemiş ve özel. .Emin diğer değişkenlerle çakışmaması yapmaktır. Onu aramaya seçilmiş olsaydı $sh_version, o zaman potansiyel olarak değişken zaten (nasıl mesela gördükleri kullanılan komut dosyalarını ele geçirmiş olabilir zshonun ile sorunları vardır $pathya $commandsbazı komut kırmak olduğunu) özel dizi / karma değişkenler (a la csh).

Bu değişkenleri desteklemeyen kabukları ek olarak, do mksh pdksh gibi bazı kabukları / o Not kaldırmak aldıkları çevreden onları ( bashboş bir isimle birini kaldırır ash, kshve bashbir içermeyen bu çevre dizeleri kaldırmak =karakteri):

$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%

$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%

$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%

Özetle, iyi (en kabukları ile desteklenen değişken adları ile sopa ve hatta kabuklarda özel olanlar kaçınarak ortam değişkenleri için büyük harf kullanmayı deneyin (ve ihraç kabuk değişkenleri için durum ya da karışık harfe) ETMEK böyle IFS, PS1, BASH_VERSION...).

Eğer böyle bir değişkeni, onları desteklemeyen, fakat onları atmayan bir kabuğa ayarlamanız gerekiyorsa, kendinizi aşağıdaki gibi yeniden ifade edebilirsiniz:

#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"

(Açıkçası, betiğin ortasında yapmanız gerekiyorsa, bu işe yaramayacak, ancak kabuk yürütme ortamını bir yeniden yürütme işlemine kaydetmek ve geri yüklemek için bu yaklaşıma bir göz atabilirsiniz ). Veya hata ayıklayıcı yaklaşımını deneyin:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"

(tek çalışmak gibi görünüyor zsh, yash, cshve tcshLinux amd64 üzerinde değil, denedim diğer kabukları (herhangi biriyle mksh, ksh93, bash, dash)).


1
mksh(ve pdksh) aslında mevcut kabuk yürütme ortamında dışa aktarılan parametreleri kullanarak, ortaya koydukları çevre işlemlerini tamamen sıfırdan inşa eder, bu nedenle bu değişkenleri bu kabuklardan geçirmenin bir yolu yoktur. (Not değişkenler olduğunu edilir geçti değişime tabidir; örneğin destek dizisi ihracat planlıyorum ben mkshbazı gün.)
mirabilos

0

Diğer yayınların işaret ettiği gibi, en yaygın kabuklar, ortam değişkenlerini adında noktalarla ayarlamaya izin vermez. Ancak, özellikle yazılımın dönemlerle ilgili önemli değerleri gerektirdiği Docker ve çağrılan programları içeren durumlar buldum.

Bununla birlikte, bu durumların her birinde, bu anahtar-değer çiftleri, programa sadece ortam değişkenlerinden başka yollarla aktarılabilir. Örneğin, Ant uygulamasında, "-propertyfile (dosyaadı)" özelliğini, değer biçimli bir özellik koleksiyonuna aktarmak için kullanabilirsiniz. Confd "-backend dosyası -dosyası (yaml dosyası)" için izin verir.

Ortam değişkenlerini "C__any_value = 'my.property.key = değer" "şeklinde geçirdim. Daha sonra ilk dosyayı oluşturmak için program çağrısını değiştirdim:

set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt

setBazlı Shell formunda ayrı bir satırda ölçer her özellik komutu,

C__any_value='my.property.key=the value'

awkKomut ile başlayan sadece ortam değişkenleri işleyecek C__sonra tek tırnak içinde bulunan değerleri ayıklamak.

Bu yöntem, ortam değişkeni değerinin, işlem programının gerektirdiği kesin biçimde ayarlanmasını gerektirir. Ek olarak, özellik değeriniz veya anahtarınız tek tırnak içerecekse, awk alan ayırıcı karakterini görünmeyecek bir şeyle değiştirmeniz ve değeri bu karakterle çevrelemeniz gerekir. Örneğin %, ayırıcı olarak kullanmak için:

$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value

(Kesin çıktı kabuğunuza bağlı olacaktır.) Kaçış teklifinin kodunu çözmek için ekstra adımlar atmanız gerekecektir.

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.