Kabuk Betiği: içindeki seçeneklerle bir değişken oluşturma


11

Aşağıdaki parametreleri ile bir rsync komutu var:

rsync -avz --{partial,stats,delete,exclude=".*"}

Bu parametreleri komut dosyasında sonra tekrar kullanmak için bir değişkenin içine koymak istiyorum. Bunun gibi bir şey:

#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2

Ben tırnak, tek tırnak, köşeli ayraçlar, herhangi bir başarı ile denedim.



Daha önce bu rotayı izlemiş olmanız: Sonuçta elde edilen son komut dizenizde boş dizeler olmadığından emin olun. Eğer öyleyse, rsync bunları parametre olarak kullanabilir ve görünmez oldukları için hata ayıklamak oldukça zordur. Boş bir ilk parametre vardı ve rsync kopyalanacak şeylerin kaynakları geçerli dizini dahil olarak yorumladı.
Joe

Yanıtlar:


12

Bir değişkene karmaşık bir komut koymak asla tavsiye edilen bir yaklaşım değildir. Bkz BashFAQ / 050 - Bir değişkene bir komut koymak için çalışıyorum, ancak karmaşık vakalar her zaman başarısız!

Değişken yerine bir işlev kullanmaya karar verirseniz ve ona argümanlar iletirseniz gereksiniminiz gerçekten basitleşir.

Gibi bir şey

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --{partial,stats,delete,exclude=".*"} "$@"
}

ve şimdi gerekli argümanları

rsync_custom /dir1 /dir2

İşlev tanımı bir bakıma oldukça basittir, $#önce sıfır olmaması gereken değişkeni kullanarak giriş bağımsız değişken sayısını kontrol ederiz . Hiçbir argüman sağlanmadığını belirten bir hata mesajı veriyoruz. Geçerli bağımsız değişkenler varsa "$@", işleve sağlanan gerçek bağımsız değişkenleri temsil eder.

Bu da komut / komut satırında yani oldukça sık kullanıyor olacak bir fonksiyon ise, kabuk başlangıç dosyaları eklemek .bashrc, .bash_profileörneğin.

Veya belirtildiği gibi, daha iyi okunabilirlik için küme genişlemesini ayrı ayrı değişkenlere genişletmek faydalı olabilir.

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --partial --stats --delete --exclude=".*" "$@"
}

5
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

Bu çalışır komutu çalıştırmak için -avzargümanlarla --partial, --statsvb .. ile VARkümesine rsyncortamda.

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

Alıntılanan form çalışmaz, çünkü parantezler tırnak içinde değil, varsayımlar içinde değil ve bir değişken genişletildikten sonra da genişletilmezler.

Komut satırı bağımsız değişkenlerini bir değişkende depolamanız gerekiyorsa, bir dizi kullanın:

args=(rsync -avz --{partial,stats,delete,exclude=".*"})

Şimdi "${args[@]}"genişleyecektir rsync, -avz, --partialfarklı kelimeler olarak, vb.

Diziler ayrıca, gerekirse koşullu olarak listeye seçenekler eklemenize izin verir, böylece şunları yapabilirsiniz:

args=(this that)
if something ; then
    args+=(another_arg)
fi
"$cmd" "${args[@]}"

1

Seçenekleri en azından bir değişkene kısmen kaydedebilirsiniz:

opts=$(echo --{ignore-case,word-regexp,count,exclude='"sys*.*"'})

Test önemlidir, çünkü maskeleme zor olabilir:

echo $opts
--ignore-case --word-regexp --count --exclude="sys*"

grep $opts bytes *.log 

Tarihi kullanmak, bir takma ad kullanmak, bir işlevi kullanmak gibi birçok alternatif olduğundan, aklıma gelen açık bir kullanım durumu yoktur. Farklı programlar arasında nadiren karmaşık bir seçenek paylaşımı vardır, bu nedenle etkileşimli kabuk için geçici bir çözüm için takma ad daha iyi bir yol gibi görünür:

alias cgrep='grep --ignore-case --word-regexp --count --exclude="sys*"'
cgrep bytes *.log

Senin örnek

VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

çalışamaz, çünkü ödev ilk boşta sona erer. Boşlukları maskelemeniz gerekir:

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

test etmek için oldukça tehlikeli bir şey, bu - sil seçeneği ile değil mi? Seçenekler tekrar "," ve tek tırnak içerebileceğinden, maskeleme çok yakında zorlaşabilir. Bir takma ad isterdim ya da tarihe güvenirim.

Birden çok oturumda sürekli kullanım için bir diğer ad ~ / .bashrc dosyasında saklanabilir. İşlevler bashrc'de de saklanabilir, ancak yalnızca parametreleri işlemek istiyorsanız, burada değerlendirilecek işleve aktarılanlara ihtiyacınız vardır.

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.