2014-04-26 15 views
11

Komut satırında çift tırnaklı boş bir dize olarak ek argümanlar olarak kabul edecek bir komut dosyası yazmaya çalışıyorum. Komut dosyasının bu argümanları, sağlanan çift tırnaklı boş dizeyle birlikte iletmesini istiyorum, ancak bunun yerine, komut yorumcusu, böyle bir argümanı boş bir dize olarak yorumlayacak gibi görünüyor ve tırnak işaretlerini ortadan kaldırıyor. Bunu yapmanın bir yolu var mı? Ben dosya dosyanın tam içinde olurdu basit bir örnek olarakBoş bir dizeyi bash komut dosyasına çift tırnak işareti ile nasıl iletirim?

:

Ben isteminde çalıştırırsanız
#!/bin/bash 
/home/myapp $1 $2 

:

$ ./script.sh arg1 "" 

betiğide "/home/myapp arg1" çalıştırır, ancak özlüyor/yok sayar ikinci argüman (""). /home/myapp arg1 ""

cevap

3

: durumunda


daha argümanlar 2'den olabilir. Örneğin, bu 2 veya daha büyükse, $2 boş olsa bile bir şeyin $2 için geçtiğini bilirsiniz (tırnak çağırarak tırnaklar kaldırılır).Aşağıdaki bu mantık uygular ve parametre geçti ama boş ise (bu durumda echo olarak) olarak adlandırılan programa "" geçirir:

#!/bin/bash 

if [ $# -ge 2 ]; then 
    if [ "$2" ]; then 
     arg2="$2" 
    else 
     arg2='""' 
    fi 
    echo "$1 $arg2" 
elif [ $# == 1 ]; then 
    echo "$1" 
fi 

Çıktı:

 
$ ./args.sh a 
a 
$ ./args.sh a "" 
a "" 
$ ./args.sh a 1 
a 1 
$ 
+0

Mükemmel, tam olarak ihtiyacım olan şey Teşekkürler! – Josh

+1

'arg2 = ' ''' bunu echo zaman' ince görünecektir, ama bunu kullanmaya çalışırsanız ('/ home/Uygulamam $ 1 $ arg2' olduğu gibi) başka bir şeye boş dize geçmek, bu kazandı Ayarı t çalışması - boş bir dize değil, iki çift tırnaktan oluşan dizgeyi geçirir. –

+0

@GordonDavisson * Bu boş dizgeyi korumasını ve yerine getirmesini istiyorum: '/ home/myapp arg1 ''' * OP'nin ne istediği tam olarak bu değil mi? –

2

Sen Backslash

$ ./script.sh arg1 \"\" 

örneğin test edilebilir kullanarak kaçamaz: Ben yürütmek yerine bu boş dize korumak ve istediğiniz echo:

$ echo \"\" 
"" 
+0

sayesinde umarım bu işe katılıyorum evet, onlar böyle boş bir dize girdiğini tespit etmek ve değiştirmek için bazı komut büyü kullanarak tırnak kaçmak için kullanıcı gerektirmeyen herhangi bir yolu yoktur çift ​​tırnak ile komut? – Josh

+0

@Josh böyle bir sihrin farkında değil. Bu ayrıştırma kabuk tarafından yapılır, böylece farklı ayrıştırma kuralları uygulamak için kabuğu değiştirmeniz gerekir. –

2

Onları ters eğik çizgilerle temizleyin veya tek tırnak içine koyun.

2

Ayrıca, bunları tek bir alıntı içine yerleştirebilirsiniz; : Senaryoya

Örneğin
]$ echo '""' 
    "" 

:

]# cat a.bash 
    #!/bin/bash   
    echo a$1b 

    ]$ ./a.sh '""' 
    a""b 

    ]$ ./a.sh "" 
    ab 
3

tamamlamak için Kaz's helpful explanation:
Eğer geçişli "[email protected]" aracılığıyla boş argümanlar da geçilecek olursa:

#!/bin/bash 

/home/myapp "[email protected]" 

Passing throu (Ör olarak geçirilen, '' veya "" veya değişken someVar ayarlanmadan ya da boş bir dize içerir "$someVar") boş olarak olarak geçirilen da bağımsız değişkenler - GH "[email protected]" özgün argümanlar tam geçirilen olarak korur. Sen examining the $# parameter tarafından Betiğinize aktarılan kaç konumsal parametreler tespit edebilen

#!/bin/bash 

# Copy the (up to) first 2 arguments - whether they're empty strings or not - 
# to a separate array. 
firstTwo=("${@:1:2}") 
shift; shift # Remove the first 2 arguments from the arguments array. 

# Invoke the app with the (up to) first 2 arguments stored in the new array. 
/home/myapp "${firstTwo[@]}" 

# Process the remaining arguments, if any. 
for a; do 
    echo "remaining: [$a]" 
done 
10

Doğru boş bir dize geçiyoruz betiğe argüman. komut kelime bölme gelen $1 ve $2 genişlemesini korumadığını

#!/bin/bash 
/home/myapp $1 $2 

:

Bunu karıştırmasını komut dosyası. Bu $1 ve $2 Birden çok kelime içeriyorsa, tek tek bu argümanlar dönüşür ve ikisinden birinin hiçbir şey genişletmek, onlar basitçe ortadan anlamına gelir.

Bu olmalıdır: Genel olarak

#!/bin/bash 
/home/myapp "$1" "$2" 

, kendi komut dosyası aşağıdaki gibi, çağrılan programa Tüm bağımsız değişkenleri geçmesine yapabilirsiniz:

/home/myapp "[email protected]" 

tırnak sadece sözdizimi kabuk vardır; argüman verilerinin kendisinin bir parçası değildirler. Eğer kabuk haline program "" yazdığınızda, işletim sistemi seviyesinde, program boş bir C dili dize alır: bir işaretçi boş byte. Tırnak yok.

Sen argüman "" (iki çift tırnak yapılmış iki karakter dizesini) geçebileceği ancak boş bir argüman değil. Bunu yapmanın bir yolu, örneğin, '""': tek tırnak içine sarın.

Kabuk sözdizimini bir meta düzeyinde işlerken ortaya çıkan tek neden: kabuk betiklerinin kaynak kodunun kaynak kodunun içinden geçirilmesi, örneğin tırnak işaretleri, boş veya başka şekilde. Kabuk, eval adında bir komutla kaynak kodunu bir argüman (veya çoklu argümanlar) olarak alır ve değerlendirir. eval önce

empty_shell_string_syntax='""' # this variable holds the characters "" 

eval empty_var=$empty_shell_string_syntax # empty_var gets set to empty string 

çağrılır, komut satırı genişleme tabidir. Bu genişleme sözdizimi $empty_shell_string_sytnax kaldırır ve içindekiler, karakterler "" değiştirir. Böylece, eval empty_var="" dizesini alır. Bunu değerlendirir ve bu nedenle empty_var, sözdizimi belirttiği gibi boş dizeye ayarlanır.

+0

Argüman referanslarını iki kez alıntılama gereği konusunda haklısınız, ancak eğer koşulsuz olarak '$ 2' (''$ 2'') yazıyorsanız, 2 numaralı argüman olsa bile _always_ (boş) argüman olarak geçecektir. geçirilen, OP amaçlanan değil; Aksine, "$ @", amaçlandığı gibi çalışır; Açıklamaların geri kalanı için +1. – mklement0

+1

@ mklement0 sözleriyle ilgili sorunu çözmek için e.g./home/myapp $ {1 + "$ 1"} $ {2 + "$ 2"}. Bu biraz dolambaçlı, fakat işleyiş biçimi "$ {var + bir şey" yapısının "bir varsayıma" yani "$ var" tanımına göre genişlemesidir - böylece eğer $ 2 $ tanımsızsa, $ {2 + "$ 2 “}' hiçbir şeyi yok eder ve yok olur; Eğer '$ 2' tanımlanmışsa (boş dizge olarak tanımlanmış olsa bile), "$ 2" ye genişler ve çift tırnaklar onu kelime bölme ve boş bırakma işleminden korur. –

0

bu deneyin:

cmd=yourcomand; 
n=0; for a in "[email protected]"; do n=$((n +1)); cmd="$cmd \${$n+\"\$$n\"}"; done 
eval $cmd 
+1

Bu kod soruyu yanıtlarken, sorunun nasıl ve/veya neden çözüldüğüne ilişkin ek bağlam sağlayarak yanıtın uzun vadeli değerini artıracaktır. –

+0

Bu, yukarıda Kaz ve Gordon Davisson notuna dayanmaktadır, teşekkürler. Bununla birlikte, genel olarak $ {X + "$ X"} 'un genişlemesinin, geçerli değerin içerdiği karakterlere bağlı olarak istenmeyen sonuçlar doğurabileceğini unutmayın. Bu nedenle, komut satırında tüm değişkenlerin genel olarak değiştirilmesi, yalnızca boş bir dizenin mevcut olduğunu doğruladıktan sonra kullanmak en iyisidir. Yukarıdaki yanıtlardan henüz genel bir çözüm göremiyorum. – alphasoup

İlgili konular