Apa beberapa kasus yang jumlah ruang penting dalam skrip bash (atau shell lain)

14

Saya telah diberitahu bahwa spasi penting dalam bashskrip shell lain dan saya tidak boleh mengubah keberadaan ruang kecuali saya tahu apa yang saya lakukan. Dengan "mengubah keberadaan" maksud saya menyisipkan spasi antara dua karakter non-spasi atau menghapus spasi antara dua karakter non-spasi, misalnya mengubah var="$val"ke var ="$val"atau sebaliknya. saya ingin bertanya

Apakah ada kasus di mana menggunakan spasi tunggal atau menggunakan beberapa ruang berurutan dalam skrip shell membuat perbedaan? .

(Tentu saja, memasukkan / menghapus spasi dalam tanda kutip membuat perbedaan, seperti mengubah dari echo "a b"menjadi echo "a b"atau sebaliknya. Saya mencari contoh selain contoh sepele ini.)

Saya telah menemukan pertanyaan ini tetapi yang satu adalah tentang menambah dan menghapus spasi antara dua karakter non-spasi yang saya tahu banyak contoh bahwa itu akan membuat perbedaan.

Bantuan apa pun akan dihargai. Sertakan lebih banyak varietas kerang jika memungkinkan.

Weijun Zhou
sumber

Jawaban:

19

Di luar tanda kutip, shell menggunakan spasi putih (spasi, tab, baris baru, carriage-return, dll) sebagai pemisah kata / token. Itu berarti:

  • Hal-hal yang tidak dipisahkan oleh spasi dianggap sebagai satu "kata".
  • Hal-hal yang dipisahkan oleh satu atau lebih karakter spasi putih dianggap sebagai dua (atau lebih) kata.

Jumlah sebenarnya spasi putih di antara setiap "hal" tidak masalah, asalkan setidaknya ada satu.

cas
sumber
Terima kasih. Saya tidak dapat menemukan contoh balasan sendiri. Aku hanya ingin memastikan.
Weijun Zhou
2
Bash juga menganggap umpan formulir dan tab vertikal sebagai spasi.
fpmurphy
benar. Saya awalnya menulis '... baris baru, dll' dan kemudian mengubahnya untuk secara eksplisit menambahkan carriage-returns. tidak sengaja menjatuhkan 'dll'.
cas
Bagaimana jika jumlah ruang begitu besar, sehingga program tidak dapat masuk ke dalam memori?
Worse_Username
7
@Worse_Username Ruang kosong tidak harus masuk dalam memori. Saya baru saja membuat skrip 48GB pada mesin dengan 8GB RAM dan 20GB swap. Itu berjalan baik-baik saja. Memang butuh 3 menit untuk mengacaukan semua spasi putih itu, tetapi pada akhirnya berhasil menjalankan echoperintah dengan banyak spasi putih antara perintah dan argumen.
kasperd
23

Ini mungkin curang, tetapi ini:

rm foo\ bar         # "delete the file named 'foo bar'"

berbeda dari ini:

rm foo\  bar        # "delete the files named 'foo ' and 'bar'"

meskipun spasi tidak ada dalam tanda kutip. ;-)

Lebih membingungkan lagi, ini:

rm \
    foo          # "delete the file named 'foo'"

berbeda dari ini:

rm \ 
    foo          # "delete the file named ' ', then run the command 'foo'"

meskipun mereka terlihat identik!

ruakh
sumber
Meskipun spasi tidak dalam tanda kutip, garis miring terbalik secara fungsional mirip dengan bentuk kutipan dan saya akan menempatkan ini dalam kategori yang sama dengan "contoh sepele" pertanyaan. (Menarik juga.)
David Z
12

Jika kita tidak berbicara tentang karakter spasi ( U+0020), tapi setiap karakter spasi ( U+0020, \n,\t , dll), maka salah satu kasus tertentu datang ke pikiran saya: Berikut-Dokumen.

Kode ini (menggunakan spasi):

cat <<- 'EOF'
<space><space>foo
EOF

Akan dicetak:

  foo

Tetapi kode ini (menggunakan tab):

cat <<- 'EOF'
<tab><tab>foo
EOF

Akan dicetak:

foo

Itu karena ( seperti yang dinyatakan POSIX ):

Jika operator redirection adalah <<-, semua karakter <tab> utama harus dilucuti dari jalur input dan garis yang mengandung pembatas trailing.

nxnev
sumber
1
Itu menarik. Saya memikirkan di sini-dokumen tetapi tidak tahu <<-operator. Terima kasih banyak.
Weijun Zhou
di sini dokumen adalah bentuk teks yang dikutip, bukan kode shell. pemisahan kata shell tidak berlaku.
cas
2

Ini juga memiliki efek ketika menulis pernyataan tugas. Seperti jika saya katakan FOO=xyzitu akan membuat variabel lingkungan bernama FOOdengan nilai xyz, tetapi jika saya memisahkan yang sama dengan spasi, ia akan berpikir bahwa saya sedang menjalankan program bernama FOOdengan arg =xyz. Jadi itu penting ketika datang ke sintaksis tertentu.

HSchmale
sumber
Biasanya FOO=xyzmembuat variabel shell internal tetapi bukan variabel lingkungan. Anda perlu set -aatau export FOO=xyzuntuk itu (yaitu menjadikannya bagian dari lingkungan sub-proses non-subkulit).
Hauke ​​Laging