Bagaimana saya bisa menggunakan nilai dari pipa dalam program pengujian?

10
wc -l | test -eq 1

Ini tidak berhasil. Saya ingin membandingkan hasil wc dengan nilai 1. Bagaimana saya bisa melakukan itu?

tr3quart1sta
sumber

Jawaban:

9

Itu tidak menjawab pertanyaan Anda tentang pipa, tetapi Anda dapat mengatur ulang:

test $(ls -l | wc -l) -eq 1 && echo "worked"

Dan ada beberapa solusi pada SO , ini menjadi yang terbaik:

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }
Oli
sumber
4

Jika Anda menggunakan Bash, Anda mungkin ingin meneliti variabel PIPESTATUS. Sebagaimana dicatat dalam panduan referensi Bash , PIPESTATUS adalah

Variabel array (lihat Array) yang berisi daftar nilai status keluar dari proses dalam pipa latar depan yang paling baru-baru ini dieksekusi (yang mungkin hanya berisi satu perintah).

Kita bisa mengetahui apa kode keluar untuk pipa ini dengan PIPESTATUS:

dmesg | grep -iw 'nnse' | wc -l

Jika sekarang Anda meminta variabel array, Anda mendapatkan status keluar merujuk ke perintah yang digunakan dalam pipa:

echo ${PIPESTATUS[@]}
0 1 0

(Dalam array yang diindeks, kode keluar di atas diwakili oleh 0 1 dan 2 dalam array karena array selalu mulai dari 0 di Bash.)

Di sini kita melihat perintah kedua mengembalikan 1, dan sisanya 0; namun, wc -lmengembalikan 0 jika tidak ada kecocokan nol, yang bukan merupakan kesalahan. Kegagalan diwakili dengan nilai non-nol, dan ada nilai kesalahan lain seperti 127 yang perintah tidak ditemukan, dan kode lagi yang mungkin spesifik untuk program yang bersangkutan.

Jika Anda ingin melihat apa kode keluar perintah tertentu dalam pipa itu, Anda bisa mengakses nilai itu. Perintah grep adalah perintah kedua dalam pipeline di atas, tetapi sebagai array mulai dari 0, kita perlu entri satu.

Jadi untuk mengetahui kode keluar perintah grep, jalankan kembali pipa di atas (karena konten PIPESTATUS akan habis jika Anda telah menjalankan echo ${PIPESTATUS[@]}) dan kemudian jalankan perintah di bawah ini, yang akan mengembalikan 1 (kode keluar):

echo ${PIPESTATUS[1]}
1

Dalam skrip, pastikan pipeline telah selesai dieksekusi sebelum Anda mencari konten dari variabel array PIPESTATUS.

Untuk contoh penggunaan menarik dari variabel array PIPESTATUS, lihat jawaban ini tentang menggabungkan pengelompokan perintah Bash dan status pipa . Anda bisa menguji variabel array dengan cara yang disarankan oleh Gilles di komentar, meskipun Anda harus terlebih dahulu menjalankan pipa lagi:

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

Ini hanya sebuah fragmen, karena saya tidak tahu jenis script apa yang Anda inginkan, tetapi saya harap mengetahui tentang PIPESTATUS mungkin berguna bagi Anda. Ada banyak variabel array Bash seperti PIPESTATUS yang bisa sangat berguna; lihat panduan referensi Bash untuk seluruh daftar, dan situs Stackexchange lainnya untuk contoh penggunaannya.

Komunitas
sumber
2

Cara paling sederhana mungkin menggunakan xargs :

wc -l | xargs -I % test % -eq 1
John Doe
sumber
1

Ini tidak mencakup setiap testkasus, tetapi jika Anda bisa menggunakan ekspresi reguler, dan grepstring pipa, itu cukup lurus ke depan karena grepmerupakan test-seperti dalam hal ini memiliki non-nol keluar ketika tidak ada yang cocok

cat file | wc -l | grep -qE '^\s*1\s*$'

Ekspresi reguler yang diperluas memungkinkan Anda untuk menutupi banyak kasus dengan teknik ini. Untuk cekikikan, test case:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s*$'; then 
    echo "'$i' matched"
  else
    echo "'$i' didn't match."
  fi
done

output:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
Zanerock
sumber