Bu argümanları benim için tırnak içine alabilecek bir senaryo yazdım
Çıktı kabuk için uygun şekilde alıntılanmışsa ve çıktıya güveniyorsanız , o zaman eval
üzerinde çalışabilirsiniz .
Dizileri destekleyen bir kabuğunuz olduğunu varsayarsak, aldığınız argümanları saklamak için bir kabuk kullanmak en iyisidir.
Eğer ./gen_args.sh
çıktıyı gibi üretir 'foo bar' '*' asdf
, o zaman çalıştırabilir eval "args=( $(./gen_args.sh) )"
adında bir dizi doldurmak için args
sonuçlar. Yani üç unsurun olacağını foo bar
, *
, asdf
.
"${args[@]}"
Dizi öğelerini ayrı ayrı genişletmek için her zamanki gibi kullanabiliriz :
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(Tırnaklara dikkat edin. "${array[@]}"
Değiştirilmemiş bağımsız bağımsız değişkenler olarak tüm öğelere genişler. Tırnaklar olmadan dizi öğeleri sözcük bölünmesine tabidir. Örneğin, BashGuide'daki Diziler sayfasına bakın .)
Ancak , eval
herhangi bir kabuk ikamesini mutlu bir şekilde çalıştıracaktır, bu nedenle $HOME
çıktıda ana dizininize genişleyecek ve bir komut ikamesi gerçekten de kabuk çalışmasında bir komut çalıştıracaktır eval
. Çıktısı, "$(date >&2)"
tek bir boş dizi öğesi oluşturur ve geçerli tarihi stdout'a yazdırır. gen_args.sh
Verileri ağ üzerindeki başka bir ana bilgisayar gibi diğer kullanıcılar tarafından oluşturulan dosya adları gibi güvenilir olmayan bir kaynaktan alırsa bu bir endişe kaynağıdır. Çıktı rastgele komutlar içerebilir. ( get_args.sh
Kendisi kötü niyetli olsaydı, hiçbir şey çıktılaması gerekmez, kötü amaçlı komutları doğrudan çalıştırabilir.)
Değerlendirme olmadan ayrıştırılması zor olan kabuk alıntılamaya bir alternatif, komut dosyanızın çıktısında ayırıcı olarak başka bir karakter kullanmak olacaktır. Asıl argümanlarda gerekli olmayan birini seçmeniz gerekir.
Seçelim #
ve script çıktısını alalım foo bar#*#asdf
. Şimdi komutun çıktısını bağımsız değişkenlere bölmek için sıralanmamış komut genişletmesini kullanabiliriz .
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
IFS
Komut dosyasında başka bir yerde sözcük bölmeye bağlıysanız ( unset IFS
varsayılan yapmak için çalışmalısınız) daha sonra tekrar ayarlamanız ve set +f
daha sonra globbing kullanmak istiyorsanız da kullanmanız gerekir.
Bash veya dizileri olan başka bir kabuk kullanmıyorsanız bunun için konum parametrelerini kullanabilirsiniz. Değiştir args=( $(...) )
ile set -- $(./gen_args.sh)
ve kullanımı "$@"
yerine "${args[@]}"
daha sonra. (Burada da tırnak işaretleri kullanmanız gerekir "$@"
, aksi takdirde konumsal parametreler kelime ayırmaya tabidir.)
eval
kullanılabilir, ancak genellikle önerilmez.xargs
de dikkate alınması gereken bir şey