Saya hanya ingin memasukkan semua file dalam direktori tertentu ke bash array (dengan asumsi tidak ada file yang memiliki baris baru dalam namanya):
Begitu:
myarr=()
find . -maxdepth 1 -name "mysqldump*" | mapfile -t myarr; echo "${myarr[@]}"
Hasil kosong!
Jika saya melakukan cara bundaran menggunakan file, sementara atau sebaliknya:
myarr=()
find . -maxdepth 1 -name "mysqldump*" > X
mapfile -t myarray < X
echo "${myarray[@]}"
Hasil!
Tetapi mengapa tidak mapfile
membaca dengan benar dari sebuah pipa?
find
danmapfile
di sini sama sekali dan bukan hanya sekadarmyarr=(mysqldump*)
? Ini bahkan akan bekerja dengan nama file dengan spasi dan baris baru.nullglob
opsi (shopt -s nullglob
) untukmyarr=(mysqldump*)
agar tidak berakhir dengan array('mysqldump*')
jika tidak ada file yang cocok.Jawaban:
Dari
man 1 bash
:Subkulit tersebut mewarisi variabel dari shell utama tetapi mereka independen. Ini berarti
mapfile
dalam perintah asli Anda beroperasi sendirimyarr
. Kemudianecho
(berada di luar pipa) mencetak kosongmyarr
(yang merupakan cangkang utamamyarr
).Perintah ini bekerja secara berbeda:
Dalam hal ini
mapfile
danecho
beroperasi pada yang samamyarr
(yang bukan shell utamamyarr
).Untuk mengubah shell utama,
myarr
Anda harus menjalankanmapfile
shell utama dengan tepat. Contoh:sumber
Bash menjalankan perintah-perintah pipa di lingkungan subkulit, sehingga setiap penugasan variabel, dll. Yang terjadi di dalamnya tidak terlihat oleh sisa shell.
Dash (Debian
/bin/sh
) dan busyboxsh
mirip, sedangkan zsh dan ksh menjalankan bagian terakhir di shell utama. Di Bash, Anda dapat menggunakanshopt -s lastpipe
untuk melakukan hal yang sama, tetapi ini hanya berfungsi ketika kontrol pekerjaan dinonaktifkan, jadi tidak dalam shell interaktif secara default.Begitu:
(
read
danmapfile
memiliki masalah yang sama.)Atau (dan seperti yang disebutkan oleh Attie), gunakan substitusi proses , yang bekerja seperti pipa umum, dan didukung di Bash, ksh dan zsh.
POSIX membiarkannya tidak ditentukan jika bagian-bagian dari pipa berjalan dalam subkulit atau tidak, sehingga tidak dapat benar-benar dikatakan bahwa setiap kerang akan "salah" dalam hal ini.
sumber
set +m; shopt -s lastpipe; x=a; echo b | read x; echo $x; set -m
Seperti yang Kamil tunjukkan, setiap elemen dalam pipa merupakan proses terpisah.
Anda dapat menggunakan berikut proses substitusi untuk mendapatkan
find
untuk berjalan dalam proses yang berbeda, denganmapfile
doa yang tersisa di interpreter Anda saat ini, memungkinkan akses kemyarr
setelahnya:b < <( a )
akan bertindak serupaa | b
dalam hal bagaimana pipa disambungkan - perbedaannya adalah yangb
dieksekusi "di sini ".sumber