Bash hata veriyor, satır 8: $ 1: ilişkisiz değişken


16

(Ben getopts daha iyi olabileceğini düşünüyorum rağmen) ayrıştırılmış girdi ile komut dosyaları olabilir böylece getopts kullanmayı öğrenmeye çalışıyorum. Sadece bölüm kullanım yüzdeleri döndürmek için basit bir komut dosyası yazmaya çalışıyorum. Sorun benim bash işlevlerinden biri ben $1işlev içinde bir değişken olarak başvuru gibi görünmüyor olmasıdır . Başvurmamın nedeni $1, get_percentişlevin tüm bağlama noktaları yerine görüntülemek için isteğe bağlı bir bağımsız değişken olarak bir bağlama noktasından geçirilebilmesidir.

Senaryo

#!/usr/bin/bash

set -e
set -u
set -o pipefail

get_percent(){
    if [ -n "$1" ] 
    then
        df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
    else
        df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
    fi
}

usage(){
    echo "script usage: $(basename $0) [-h] [-p] [-m mount_point]" >&2
}

# If the user doesn't supply any arguments, we run the script as normal
if [ $# -eq 0 ];
then
    get_percent
    exit 0
fi
# ...

Çıktı

$ bash thing.sh
thing.sh: line 8: $1: unbound variable

$ bash -x thing.sh
+ set -e
+ set -u
+ set -o pipefail
+ '[' 0 -eq 0 ']'
+ get_percent
thing.sh: line 8: $1: unbound variable

Bunun bir ilgisi olduğunu düşünmüyorum getopts, değil mi? Komut dosyanız -uçağrı yapmadan önce nedeniyle çıkıyor getopts.
ilkkachu

@ikkachu hayır sanmıyorum. Ama şimdi başlığı değiştirebileceğimden emin değilim.
Timothy Pulliam

Bir sorudaki etiketlerin hemen altında, yazının altında küçük bir "düzenle" metni olmalıdır
ilkkachu

Yanıtlar:


31

set -uayarlanmamış bir değişkene başvurursanız, tam olarak açıkladığınız şekilde iptal edilir. Senaryonuzu argüman olmadan çağırıyorsunuz, bu yüzden get_percentargüman olmadan çağrılıyor ve $1ayarlanmamaya neden oluyor .

İşlevinizi çağırmadan önce bunu kontrol edin veya varsayılan genişletmeleri kullanın ( başka bir şeye ayarlanmamışsa ${1-default}genişler default).


Bundan şüpheliydim, ama bunun bir yolunu düşünemedim. Varsayılan genişleme düzeltildi gibi görünüyor. Çok teşekkür ederim!
Timothy Pulliam

8
Özellikle, [ -n "${1-}" ]parametrenin ayarlanıp ayarlanmadığını görmek için (boş bir varsayılan değerle) kullanılabilir; veya [ "${1+x}" = x ]boş olsa bile ayarlanıp ayarlanmadığını görmek için.
ilkkachu

Kullanmaya rağmen hala if [[ -n ${1-default} ]]
sınırsız

@ChaitanyaBapat Hala başlamıştı unbound variableyanı kullandığım kadar :-yerine -. Yani, en azından benim için, ${1:-default}yalnız kimse hatayı kaldırdı.
Adam Badura

7

Bunun etkisi set -u.

$#Fonksiyonun içini kontrol edebilir ve $1ayarlanmamışsa referans vermekten kaçınabilirsiniz .

İle $#parametre sayısına erişebilirsiniz. Global bağlamda, betiğe parametre sayısı, bir işlevde işleve parametre sayısıdır.

Soru bağlamında,

if [ $# -ge 1 ] && [ -n "$1" ]
then
    df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
else
    df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
fi

Kullanmanız gerekip [ $# -ge 1 ] && [ -n "$1" ]gerekmediğini unutmayın [ $# -ge 1 -a -n "$1" ], çünkü bu önce değerlendirir $1ve sonra kontrol eder $#.


$ # 'I nasıl kullanacağınızı ve nasıl kontrol edeceğinizi açıklayabilir misiniz? Teşekkürler
Chaitanya Bapat

1
Bir örnek ekledim.
RalfFriedl

3

Bu ayarlandığından emin olun ve sadece kullanımı bashkontrol edin ( ilk parametre, hepsi budur; çift tırnaklı olduğunda, hiçbir değeri yoksa tamamen kaybolur ve bu da yakalanmasını önler ):$1"$@"$1$@set -u

get_percent() {
    df -h "$@" | awk 'NR>1 { printf "%s\t%s\n", $1, $5 }'
}

Ayrıca, çıktınız iki değer arasında {space} {tab} {space} elde etmemeniz için satırın geri kalanını biraz değiştirdim, ancak sadece bir {tab} elde edersiniz. İki görünmez alanı gerçekten istiyorsanız, awkkullanmak için değiştirin printf "%s \t %s\n", $1, $5.


Buna bakmam gerekecek. Bu değişken türünü bilmiyorum. Teşekkürler
Timothy Pulliam

@TimothyPulliam Ben kısa bir açıklama ekledik $@sizin için
roaima
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.