egrep: ekspresi kosong (sub): Perilaku tak terduga untuk bash Loop di Mac

2

Saya memiliki skrip pengisian yang disederhanakan pada Mac OS X 10.12:

#!/usr/bin/env bash

echo "=> BASH_VERSION = $BASH_VERSION"
function testForLoopMac {
local file
for file
do
    echo File=$file
done | egrep "$file"
}

function testForLoopMacBis {
local file
for file
do
    echo File=$file
done | egrep "$file|OK"
}

testForLoopMac $@

testForLoopMacBis $@

Tetapi hasil ketika saya menjalankan adalah:

$ testForLoopMac.sh example.pdf 
=> BASH_VERSION = 3.2.57(1)-release
File=example.pdf
egrep: empty (sub)expression

Pada Debian / Ubuntu Linux, hasilnya adalah:

$ testForLoopMac.sh example.md 
=> BASH_VERSION = 4.3.30(1)-release
File=example.md
File=example.md

Sunting: Dengan bash4 di Mac OSX 10.12:

Saya mengubah shebang ke #!/usr/bin/env bash4dan hasilnya sama:

$ testForLoopMac.sh example.md 
=> BASH_VERSION = 4.4.12(1)-release
File=example.md
egrep: empty (sub)expression

Sunting: Terima kasih kepada kalian, saya mengerti perbedaan perilaku di Linux atau BSD egrepkarena pada saat egreppelaksanaan variabel dapat kosong.

Saya akan menggunakan karena itu, regExp berikut:

egrep "File=|OK"

Terima kasih lagi :)

SebMa
sumber
Bisakah Anda menambahkan BASH_VERSIONkeduanya dari macOS dan dari Linux?
nohillside
1
Saya pikir skrip terlalu disederhanakan untuk menunjukkan maksud Anda yang sebenarnya. Apakah argumen pada skrip dianggap sebagai ekspresi reguler?
0942v8653
@patrix Saya memperbarui Pertanyaan dengan informasi versi bash karena komentar hanya menggunakan format mini-Markdown yang
merepotkan
Untuk mengedit pertanyaan itu perlu dimasukkan informasi seperti itu adalah hal yang lebih disukai untuk dilakukan daripada menambahkannya di komentar karena komentar itu fana.
grg
@ 0942v8653 skrip ini ideal untuk menunjukkan bagaimana eksekusi pada macOS dan Linux berbeda. Yang mana semua pertanyaannya adalah tentang :-)
nohillside

Jawaban:

2

Shell memperluas subekspresi $filedi sisi kanan pipa sebelum variabel memiliki nilai apa pun. Jadi di kedua fungsi egrepsebenarnya disebut dengan string kosong di tempat $file. Fungsi pertama tidak menimbulkan kesalahan karena pola kosong adalah parameter yang valid untuk egrepMacOS dan Linux. Dalam fucntion kedua perbedaan ikut bermain karena subekspresi kosong menyebabkan BSD egrep(yang digunakan pada macOS) untuk melempar kesalahan.

Contoh:

echo foo | egrep "|foo"
egrep: empty (sub)expression

sebagai contoh lain dengan $filetidak memiliki nilai

echo foo | egrep "$file|foo"
egrep: empty (sub)expression

Jadi, sebagai solusi dalam penggunaan fungsi Anda:

egrep -e "$file" -e 'OK'

Saya tidak tahu mengapa Anda menggunakan egrepketika Anda mencari string tetap.

fd0
sumber
Perluasan dilakukan dengan bashtidak oleh egrep, jadi saya sedikit berjuang untuk memahami kalimat pertama Anda.
nohillside
@patrix Yap, Anda benar. Akan diedit.
fd0
Terima kasih. Saya masih bertanya-tanya mengapa ini bekerja di Linux
nohillside
@patrix Perbedaan antara BSD grepdan GNU grep. GNU greptidak mengeluh tentang subekspresi kosong untuk satu hal.
fd0
@patrix Mungkin, di linux, variabel tidak terganggu ketika loop selesai.
SebMa