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 argssonuç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 , evalherhangi 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.shVerileri 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.shKendisi 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:
IFSKomut dosyasında başka bir yerde sözcük bölmeye bağlıysanız ( unset IFSvarsayılan yapmak için çalışmalısınız) daha sonra tekrar ayarlamanız ve set +fdaha 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.)
evalkullanılabilir, ancak genellikle önerilmez.xargsde dikkate alınması gereken bir şey