2013-05-23 20 views
14

Bash komut dizesi, bir dize olarak bir dosya adı (veya göreli yol) alır, ancak daha sonra bu dosyadan okumalıdır. Ben sadece bir dosyadan okuyabilseydim, bunu doğrudan senaryonun içinde (tırnaksız) bir edebi olarak ilan edersem ... bu, başlangıçta örtülü olarak dizeleri olduğu için argümanlar için imkansızdır. Gözlemleyin:bash: dize değişkeni dosya adı/yolu olarak yorumla

a="~/test.txt" 
#Look for it 
if [[ -a $a ]] ; then 
    echo "A Found it" 
else 
    echo "A Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $a 

b='~/test.txt' 
#Look for it 
if [[ -a $b ]] ; then 
    echo "B Found it" 
else 
    echo "B Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $b 

c=~/test.txt 
#Look for it 
if [[ -a $c ]] ; then 
    echo "C Found it" 
else 
    echo "C Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $c 

verimleri: Yukarıda belirtildiği gibi, ben alıntı dizeleri olsun aynı davranışı elde beri yukarıda rutinleri için bir komut satırı argümanı geçemez

A Error 
./test.sh: line 10: ~/test.txt: No such file or directory 
B Error 
./test: line 12: ~/test.txt: No such file or directory 
C Found it 
Hello 

.

+3

"~/test.txt" ve '~/test.txt', ev dizininizde ~ genişlemesini durdurur. ~/test.txt işlenmemiş olduğu için çalışır. ~ Notasyonu kullanmayı bırakın veya alıntılar kullanmayı bırakın .... –

+1

Sadece komut dosyasının komut satırı argümanını ('$ 1') kullanırsanız, o zaman ev dizini genişlemesi betik çağrılmadan önce yapılmış olduğundan her şey iyi çalışır. – rici

+0

@rici Evet, komut dosyasının komut satırından veya başka bir komut dosyasından çağrıldığında '' 'yazılmaması şartıyla. Senaryosu başka bir programdan (_a literal_ '~) geçen başka bir programdan farklı bir hikaye. Bu, diğer programda düzeltilmesi gereken bir hata olurdu; ama eğer kendi senaryosunda böyle bir durumla ilgilenmek istiyorsa, muhtemelen “eval” e ihtiyaç duyar. – Uwe

cevap

28
Bu-işlem kurallarının bir parçasıdır. Bash kılavuzunda, ~ belirtildiğinde bu genişletmenin yapılmadığı açıkça belirtilmiştir.

Geçici Çözüm 1

~ alıntı yapma.

file=~/path/to/file 

Eğer dosya geri kalanını alıntı gerekirse: (Bu bir bahçe mahsulü kabuk tamamen yasal.)

file=~/"path with spaces/to/file" 

Geçici çözüm 2

kullanın $HOME~ yerine.

file="$HOME/path/to/file" 

BTW:

Kabuk değişken tipleri Kabuk değişkenlerinin türleri hakkında biraz karıştı gibi görünüyor.

Her şey bir dizedir.

İçeriye girene kadar tekrarlayın: Her şey bir dizedir. (tamsayılar hariç ama onlar konum çoğunlukla AFAIK dizeleri üstünde kesmek Ve diziler, ancak diziler dizeleri ait konum..)

Bu bir kabuk dizedir: "foo". Yani "42". Yani 42. Yani foo. Bir şeyleri alıntılamak zorunda değilsen, mantıklı değil; kim "ls" "-la" "some/dir" yazmak ister?

+0

'dosya = ~"/boşluklu/dosya/yol "' da çalışmıyor. Benim için "dosya = ~ /" yolunu boşluk/to/dosya "' – sercxjo

+1

@sercxjo yazmak zsh üzerinde çalışır ve bash üzerinde çalışmıyor. Yani '~ /" 'daha taşınabilir. –

+1

@sercxjo (ve Nick) düzeltildi – michaelb958