Bash'de tırnak içine alınmış bir dize içinde bir ortam değişkeni nasıl kullanılır


95

Bir bash komut dosyasında aşağıdakilerin çeşitli biçimlerini denedim:

#!/bin/bash
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

Ancak COLUMNSortam değişkenini doğru şekilde genişletmek için sözdizimini alamıyorum .

Aşağıdakilerin çeşitli biçimlerini denedim:

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W $COLUMNS'

ve

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W ${COLUMNS}'

ve

eval svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

Öneriler?


öyleyse bu örnekler sizin durumunuzda ne üretir? Peki ne üretmelerini istiyorsunuz?

komut dosyası dışındaki komut çalışıyor mu?
dfa

Denediniz misvn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W ""$COLUMNS"
Qian Chen

BTW, $@tırnaksız kullanmak onu tamamen aynı kılar $*- yani "foo bar"iki ayrı argümana bölünür foove bar. Orijinal argüman listesini size verildiği gibi korumak istiyorsanız, istersiniz "$@".
Charles Duffy

Yanıtlar:


16

Emin değilseniz, terminalde 'cols' isteğini kullanabilir ve SÜTUNLARI unutabilirsiniz:

COLS=$(tput cols)

Sebep ne olursa olsun, bu sayfadan çalışabildiğim tek çözüm buydu (11 / Mayıs 10:38 ET itibariyle). Teşekkürler
Jamie

407

Başlıkta sorulan genel sorunun cevabını arayan Google aracılığıyla buraya gelenler için (benim gibi) kısa bir not / özet. Aşağıdakilerden herhangi biri, tırnak içindeki kabuk değişkenlerine erişim sağlamak için çalışmalıdır:

echo "$VARIABLE"
echo "${VARIABLE}"

Tek tırnak kullanımı ana konudur. Göre Bash Reference Manual :

Karakterleri tek tırnak içine almak ( '), tırnak içindeki her karakterin değişmez değerini korur. Ters eğik çizgiden önce gelse bile, tek tırnak işaretleri arasında tek bir alıntı oluşmayabilir. [...] çift tırnak içine yerleştirme karakterleri ( ") hariç olmak üzere, tırnak içindeki tüm karakterlerin değişmez değerini korur $, `, \, ve, geçmiş genişleme etkinken, !. Karakterler $ve `çift tırnak içinde özel anlamlarını korurlar (bkz. Kabuk Genişletmeleri). Aşağıdaki karakterlerden biri tarafından bitirilen ters eğik çizgi sadece özel bir anlam korur: $, `, ",\veya yeni satır. Çift tırnak içinde, bu karakterlerden birinin izlediği ters eğik çizgiler kaldırılır. Özel bir anlamı olmayan karakterlerden önceki ters eğik çizgiler değiştirilmeden bırakılır. Çift tırnak, önünde ters eğik çizgi ile çift tırnak içine alınabilir. Etkinleştirilirse, !çift ​​tırnak içinde bir ters eğik çizgi kullanılarak öncelenmedikçe geçmiş genişletme gerçekleştirilir . Önündeki ters eğik çizgi !kaldırılmaz. Özel parametreler *ve @çift ​​tırnak içindeyken özel anlamlara sahiptir (bkz. Kabuk Parametre Genişletme).

Soruda sorulan özel durumda, $ COLUMNS, standart olmayan özelliklere sahip özel bir değişkendir (yukarıdaki lhunath'ın cevabına bakın).


20
Tek tırnak söz konusu olduğunda, bu geçici çözüm yardımcı olabilir: 'before'"$variable"'after'(bu yanıtta belirtildiği gibi: stackoverflow.com/a/13802438/2254346 )
MakisH

Mükemmel cevap! Tek tırnak içinde benim env değişkenime başvurma konusunda aynı sorunu yaşadım. Tek teklifimi çift tırnak olarak değiştirdiğimde, env değişkenim beklendiği gibi genişletiliyordu.
Binita Bharati

14

Şunlara dikkat edin COLUMNS:

  1. Bir ortam değişkeni DEĞİLDİR . Bash'in kendisi tarafından ayarlanan sıradan bir bash parametresidir.
  2. Bir SIGWINCHsinyal alındığında otomatik olarak ayarlanır .

Bu ikinci nokta genellikle COLUMNSdeğişkeninizin bir bash betiğinde değil , yalnızca etkileşimli kabuğunuzda ayarlanacağı anlamına gelir .

Komut dosyanız stdinterminalinize bağlıysa, terminalinize sorarak terminalinizin genişliğine manuel olarak bakabilirsiniz:

tput cols

Ve bunu SVN komutunuzda kullanmak için:

svn diff "$@" --diff-cmd /usr/bin/diff -x "-y -w -p -W $(tput cols)"

(Not: ;-) alıntı yapmalı "$@"ve onlardan uzak durmalısınız eval)


Bilgi için teşekkürler; neler olduğunu bilmek, konuya bir katarsis duygusu getirir.
Jamie

2

Aşağıdaki komut dosyası benim için birden çok değer için çalışıyor $COLUMNS. Acaba COLUMNSbu görüşmeden önce ayar yapmıyor musunuz?

#!/bin/bash
COLUMNS=30
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

$COLUMNSDoğru ayarlanıp ayarlanmadığını görmek için betiğinizin içinde yankılanabilir misiniz ?


Boo, tıslama re: tırnaksız $@- tek bir parametreyi "two words"iki ayrı parametreye bölen twove words. Olmalı "$@"o verildi aynen içinden argüman listesi geçmek.
Charles Duffy

0

Doğru yapıyorsunuz, sanırım başka bir şey hatalı (COLUMNS dışa aktarılmıyor mu?).

Bu durumlarda hata ayıklamanın bir püf noktası, özel bir komut (programlama dili adamları için bir kapanış) yapmaktır. Aşağıdakileri yapan diff-column adlı bir kabuk betiği oluşturun:

exec /usr/bin/diff -x -y -w -p -W "$COLUMNS" "$@"

ve sadece kullan

svn diff "$@" --diff-cmd  diff-columns

Bu şekilde, kodunuz okunması daha temiz ve daha modülerdir (yukarıdan aşağıya yaklaşım) ve fark sütunları kodunu tamamen ayrı ayrı test edebilirsiniz (aşağıdan yukarıya yaklaşım).


Komut satırı, işlem çatallanmadan önce ayrıştırılır, bu nedenle COLUMNS'u dışa aktarmamak sorun olamaz.
Peter van der Heijden

1
Kodunu bir bash betiğinin bir parçası olarak söylüyor, bu nedenle sorun olabilir.
Colas Nahaboo
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.