Kabuk değişkeni adı kısa çizgi veya kısa çizgi (-) içerebilir mi?


38

-Kabuktaki değişkenlerde kullanamıyorum . Kullanabilmenin bir yolu var mı, çünkü adlandırılmış değişkenlere bağlı bir betiğim var:

$export a-b=c
-bash: export: `a-b=c': not a valid identifier

$export a_b=c

İlk önce verilen hatayı atar, ikincisi iyi çalışır.



Kabuklar genellikle bu gibi değişken adlarına izin vermez. Kabuğu bypass etmeniz gerekebilir, belki de değişkenleri komutunuzun ortamına yükleyen özel bir C programı ile bile. Bu yanlış özelliği düzeltemez misiniz (olası güvence riski bile)?
vonbrand

Yanıtlar:


47

-Değişken adına izin verilen Bourne tarzı bir kabukla hiç karşılaşmadım . Yalnızca ASCII harfleri (her iki durumda da) _ve rakamlar desteklenir ve ilk karakter bir rakam olmamalıdır.

Kabuk kısıtlamalarına uymayan bir ortam değişkeni gerektiren bir programınız varsa, programı programla başlatın env.

env 'strange-name=some value' myprogram

Bazı mermilerin (örneğin modern çizgi , mksh, zsh) ortamdan hoşlanmadıkları değişkenleri kaldırdığını unutmayın. ( Shellshock , insanların çevre değişkeni adları konusunda daha temkinli davranmasına neden oldu, bu nedenle kısıtlamaların zaman içinde daha sıkı hale gelmesi, daha fazla izin vermemesi olasıdır.) Bu nedenle, adı özel karakter içeren bir değişkeni bir programa aktarmanız gerekirse, doğrudan aralarında bir kabuk olmadan ( env 'strange-name=some value' sh -c'…; myprogram'çalışabilir veya çalışmayabilir).


Artık çalışmıyor.
Jesse Glick

4
@JesseGlick Evet öyle. (“Çalışmama” yı tanımladıysanız yorumunuz faydalı olacaktır: hangi verilerle? İstenen etki yerine etki nedir? Ve hangi uygulamanın envhangi işletim sisteminde kullanıldığını
söyleseydiniz

Üzgünüm. Tüm güncellemeleri, ile Ubuntu Yakkety envdan coreutils, shdan dash: env 'with-dashes=value' bash -c 'env | fgrep dashes'eserler ancak env 'with-dashes=value' sh -c 'env | fgrep dashes'baskılar şey. Yani, envkendisi gayet iyi, ancak Dash bu değişkenleri özellikle engelliyor gibi görünüyor. Dolayısıyla, söz konusu program tipik bir #!/bin/shbaşlığa sahip bir kabuk sarmalayıcı vasıtasıyla başlatılırsa , bu tür değişkenlere geçmenin açık bir yolu yoktur. örnek geçici çözüm
Jesse Glick

@JesseGlick Değişkeni kaldıran çizgi budur. envArada bir kabuk olmadan, bu değişken adına ihtiyaç duyan programın arama sitesine daha yakın bir süre kullanmanız gerekir. Dash, adı beğenmediği değişkenleri kaldırmada yalnız değildir.
Gilles 'SO- kötü olmayı'

1
Doğru @JesseGlick o işin için kullanılan bazı şeyler olabilir artık çalışmaz olsa: beri Shellshock , insanlar değişken adları hakkında daha fazla muhafazakar hale gelmiştir ve çizgi aslında yaptığımız değişiklik bu cevabı (yazmış beri olmasa da Shellshock bir sonucu olarak, ama aynı satır boyunca bir hata önlemek için). Cevabımı notu ekledim.
Gilles 'SO- kötülük olmayı bırak'

15

Bash'de mümkün değil.

Kullanım kılavuzundaki Tanımlar bölümünden bash:

isim Sadece alfasayısal karakterler ve alt çizgilerden oluşan ve alfabetik bir karakter veya alt çizgi ile başlayan bir kelime. Ayrıca bir tanımlayıcı olarak da adlandırılır.

Kullanım kılavuzundaki Parametreler bölümünden bash:

Bir parametre, değerleri saklayan bir varlıktır. Özel Parametreler altında bir ad, numara veya aşağıda listelenen özel karakterlerden biri olabilir. Değişken, ad ile gösterilen bir parametredir.


2
Man sayfalarının kullanışlılığını bir kez daha göstermek için +1
ktf

2
Eski yazı biliyorum ama yeni başlayanlar için man sayfalarının oldukça şifreli olabileceğini belirtmek istiyorum. Daha iyi açıklamalar / örnekler aramaya ihtiyacım olduğunda hala zamanım var. Başlarına asla gelmediğini söyleselerdi herkes yalan söylerdi.
TCZ8

1
@ TCZ8 Bana, man sayfalarının 'kriptik' olduğunu düşündüklerini söyleyen tek kişi, hata mesajları okumayan ve okumaya ihtiyaç duyduklarının hemen üstüne atlayan her şeyi gözden kaçıran aynı insanlar.
Miles Rout

13

Dolaylı bir referans kullanarak tirelenmiş bir değişkene erişebilirsiniz.

$ env 'my-hyphenated-variable=hello' /bin/bash
$ name='my-hyphenated-variable'
$ echo ${!name}
hello

1
Bu yorumu okuyana kadar bu işlevselliği hiç duymamıştım. Bana verilen cevaptan daha kolay bir çözüm sundu.
DrStrangepork

7
Bu davranış, bash'ın yeni sürümlerinde devre dışı bırakıldı. Durumun ayrıntılı bir analizi için stackoverflow.com/questions/36989263/… adresine bakın .
Nicolas Dudebout

6

Komut dosyanız değişken adların tireye sahip olmasına bağlıysa , bu bir programlama hatasıdır. Değişken adlarının kısa çizgi içermesi için düzenli olarak kullandığınız araçlar nedeniyle sizin için uygunsa, daha fazla ve farklı araçlar öğrenmeniz gerekebilir.

Kullandığınız denediniz mi tr çizgi içine tire dönüştürmek için?

hyphenated_name="a-b"
unhyphenated_name=$(echo $hyphenated_name | tr '-' '_')
declare -x $unhyphenated_name="some value"

Bash, '-' işlev isimlerinde görünmesine izin veriyor. Bunu her zaman yapıyorum. Örneğin:

function foo-bar() {
   echo "$@"
}

2

Dash ( -) karakteri bir break karakteridir ve değişken adlarının bir parçası olarak izin verilmez. Alıntılanan değişkenlerle bunu kırmanın yolları vardır, ancak ayrıştırılması gerçekten sorunludur. Bash içindeki değişken isimler bağlamında, özellikle kaşlı ayraçlar, parantez, operatör karakterleri ve tırnak işaretleri içinde özel anlamları olan başka karakterler de vardır. (örneğin {}()=+-&'"ve daha fazlası)

Bence pratik olarak senaryoyu oluşturacak başka bir paradigma bulmalısın. "Değişken değişken isimleri" hakkında diğer dillerden bir takılma fikriniz olabilir. Bu genellikle kabuk komut dosyalarında iyi bir fikir değildir.

Bunu düzenlerseniz veya içeriğinizin ayrıntılarıyla ve ne yapmaya çalıştığınızla ilgili yeni bir soru sorarsanız, komut dosyası için iyi bir yol önerebiliriz.


2

Bash kılavuzu bir "isim" olarak tanımlar:

Yalnızca harflerden, sayılardan ve alt çizgilerden oluşan ve bir harf veya alt çizgi ile başlayan bir 'kelime'. 'İsimler kabuk değişkeni ve işlev isimleri olarak kullanılır. 'Tanımlayıcı' olarak da adlandırılır.

Yani adda tire kullanamazsınız.


0

Çoğu kabuk, değişken adları için yalnızca az, AZ, 0-9 ve _'i destekler. Bu sayfadaki ikinci öğeyi oku .


0

Env ve sed ile oynayabilirsiniz.

Örnek olarak, bu 'ELASTICSEARCH_CLUSTER-NODES' değişkenini okumam gerekiyordu.
Env komutu şunu verir:

~ $ env
ELASTICSEARCH_CLUSTER-NODES=elasticsearch:9200
JAVA_ALPINE_VERSION=8.212.04-r0
HOSTNAME=17eb9e7fec4c
...

Yani değişkeni çıkarmak için:

ESHOST=`env | sed -n 's/ELASTICSEARCH_CLUSTER-NODES=\(.*\)/\1/p'`

-1

Bash değişkenleri için yalnızca harflerin, sayıların ve alt çizgilerin uygun olduğuna inanıyorum. Pek çok programlama dilinde durum budur (javascript bir istisnadır).

Komut dosyanızın bu değişken adı türlerine bağlı olmamasını öneririm.

Aslında, değişken isimlerini diğer isimlerle değiştirebilecek şekilde programlamaya çalışmalısınız ve bu bir fark yaratmaz. Genel olarak, değişken isimleri değişkenin içindekileri tanımlamalıdır. Bu hata ayıklamayı çok kolaylaştırır; sizin için değilse, o zaman kodu çözmeye çalışan bir sonraki geliştirici için.


-1

Sen kullanabilirsiniz envhiphens ile set ve unset ortam değişkenlerine komutu "-".

Ayarlayabilmek için komutu çalıştırmak için env kullanmalısınız: env command. Değişkenleri bu şekilde iletirsiniz:

env a-b=c command

Şununla çalıştığını görün:

env a-b=c env

veya netleştirmek için:

env a-b=c env|grep 'a-b'
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.