Saya mencoba untuk menyimpan beberapa baris dalam variabel bash, tetapi sepertinya tidak berhasil.
Misalnya, jika saya mencantumkan /bin
satu file per baris dan menyimpannya $LS
, maka saya meneruskan $LS
sebagai stdin wc
, selalu mengembalikan 1:
$ ls -1 /bin | wc -l
134
$ LS=$(ls -1 /bin); wc -l <<< $LS
1
Jika saya mencoba menampilkan ke layar, saya mendapatkan berbagai hasil: echo
mencetak semua baris pada satu baris, sementara printf
hanya mencetak baris pertama:
#!/bin/bash
LS=$(ls -1 /bin)
echo $LS
printf $LS
Jadi, variabel bash dapat berisi banyak baris?
printf "%s\n" $LS
akan melakukannya.wc
dan perintah lainnya:wc -l <<< "$LS"
printf '%s\n' "$LS"
jika Anda ingin melihat baris baru. Itu salah ketik, perbaiki!Baris baru dalam variabel.
LS=$(ls -1)
set variabelLS
ke output darils -1
(yang menghasilkan output yang sama sepertils
, omong-omong, kecuali ketika output pergi ke terminal), dikurangi trailing newlines.Masalahnya adalah Anda menghapus baris baru saat Anda mencetak nilainya. Dalam skrip shell,
$LS
tidak berarti "nilai variabelLS
", itu berarti "mengambil nilaiLS
, membaginya menjadi kata sesuai denganIFS
dan menafsirkan setiap kata sebagai pola gumpalan". Untuk mendapatkan nilaiLS
, Anda perlu menulis"$LS"
, atau lebih umum untuk menempatkan$LS
antara tanda kutip ganda.echo "$LS"
mencetak nilaiLS
, kecuali dalam beberapa shell yang menginterpretasikan karakter backslash, dan kecuali untuk beberapa nilai yang dimulai dengan-
.printf "$LS"
mencetak nilaiLS
asalkan tidak mengandung persen atau karakter backslash dan (dengan sebagian besar implementasi) tidak dimulai dengan-
.Untuk mencetak nilai
LS
tepatnya, gunakanprintf %s "$LS"
. Jika Anda ingin baris baru di akhir, gunakanprintf '%s\n' "$LS"
.Perhatikan bahwa
$(ls)
secara umum tidak ada daftar file dalam direktori saat ini. Ini hanya berfungsi ketika Anda memiliki nama file yang cukup jinak. Untuk mendapatkan daftar nama file (kecuali file dot), Anda perlu menggunakan wildcard:*
. Hasilnya adalah daftar string, bukan string, sehingga Anda tidak dapat menetapkannya ke variabel string; Anda bisa menggunakan variabel arrayfiles=(*)
di shell yang mendukungnya (ksh93, bash, zsh).Untuk informasi lebih lanjut, lihat Mengapa skrip shell saya tercekik di spasi putih atau karakter khusus lainnya?
sumber
Yang disebutkan di atas
adalah satu-satunya solusi yang benar.
Biarkan saya menunjukkan bahwa solusi yang diusulkan lainnya, baik dengan
echo
danprintf
, tidak berfungsi dengan baik:(Satu juga dapat menguji dengan
V=$(printf 'line0:\\n\\n\nline1.\n') printf '%s\n' "$V"
dan variasi.)Sedangkan
\n
dalam nama file mungkin tidak umum, simpangit diff
ke dalam variabel, dan peluang Anda untuk menemukan\n
peningkatan literal secara dramatis.sumber
ksh
danzsh
juga mendukungprint -r -- "$LS"
danzsh
juga memilikiecho -E - $LS
.csh
memilikiecho $LS:q
meskipun itu tidak menampilkan karakter baris baru jika $ LS kosong, dan mendapatkan nilai multiline menjadi $ LS di tempat pertama cukup rumit di csh.