Buradaki sorun boru hattında ki cat "$filename" | wc -l
, dosya bulunmadığında cat
bir hata ile çıkacak, ancak wc -l
başarılı bir şekilde aldığı 0 metin satırını sayar. cat
. Boru hattındaki son komutun çıkış durumu, boru hattının bir bütün olarak nihai durumu olarak değerlendirilir, bu nedenle tüm boru hattının başarılı olduğu kabul edilir. Bunun gibi:
$ cat nosuchfile | wc -l
cat: nosuchfile: No such file or directory
0
$ echo "$?"
0
Normalde bash'ta, bir komut satırında bireysel komut durumlarını PIPESTATUS
dizi, şöyle:
$ cat nosuchfile | wc -l
cat: nosuchfile: No such file or directory
0
$ echo "${PIPESTATUS[@]}"
1 0
... ancak bu, komut genişletme komutunda bir boru hattıyla çalışmaz $( )
, çünkü bu boru hattı bir alt kabukta çalışacak ve PIPESTATUS
alt kabuktan yayılamaz; yalnızca son durum ana kabuğa geri döndürülür:
$ line_count=$(cat nosuchfile | wc -l)
cat: nosuchfile: No such file or directory
$ echo "${PIPESTATUS[@]}"
0
Peki bu konuda ne yapabilirsin? Şey, l0b0'ın dediği gibi, bir olasılık ... pipefail
seçeneği. Komut dosyasının tamamı için bunu yapmak zorunda değilsiniz, yalnızca komut değiştirme içinde yaparak belirli bir alt kabuk için ayarlayabilirsiniz:
$ line_count=$(set -o pipefail; cat nosuchfile | wc -l)
cat: nosuchfile: No such file or directory
$ echo "$?"
1
Bu özel komut için, boru hattını da ortadan kaldırabilirsiniz (buna ne denir? İşe yaramaz kedi kullanımı veya UUOC ) ve sahip wc
dosya adını parametre olarak ileterek doğrudan dosyadan okuyabilir:
$ line_count=$(wc -l nosuchfile)
wc: nosuchfile: open: No such file or directory
$ echo $?
1
... veya bir giriş yönlendirmesi kullanarak:
$ line_count=$(wc -l <nosuchfile)
-bash: nosuchfile: No such file or directory
$ echo $?
1
Bu iki seçenek arasında birkaç fark vardır: dosya adını iletirseniz wc
(ve var), dosya adının yanı sıra satır sayısını da gösterecektir:
$ line_count=$(wc -l realfile.txt)
$ echo "$line_count"
6 realfile.txt
... yönlendirme seçeneği ile olmaz. Ayrıca, ikinci seçenekle kabuk dosyayı açmaktan (ve açık dosya tanıtıcısını dosyaya teslim etmekten) sorumludur. wc
komut), öyleyse bu başarısız olursa hata veren kabuktur (hata mesajının "-bash" ifadesinden geldiğini unutmayın wc
) ve wc
asla kaçmaz.
cmd_return_code
Komut ikamesinde boru hattının çıkış durumuna; yani, boru hattındaki son komutun çıkış durumu (wc -l
). İstediğin buysa, farklı bir şey yaptığına dair hangi kanıtın var? Farklı bir şey istiyorsanız, nedir? (P.S.Yetkin Komutanınız bir UUOC (useless)cat
).line_count=$(wc -l < "$filename")
daha verimli olurdu ve istediğiniz sonuçları size verebilir.)