it-swarm-eu.dev

Bash: Jak číst jeden řádek najednou z výstupu příkazu?

Snažím se číst výstup příkazu v bashu pomocí while loop.

while read -r line
do
    echo "$line"
done <<< $(find . -type f)

Výstup jsem dostal

[email protected]:~/tmp$ bash test.sh
./test.py ./test1.py ./out1 ./test.sh ./out ./out2 ./hello
[email protected]:~/tmp$ 

Poté jsem to zkusil

$(find . -type f) | 
while read -r line
do
    echo "$line"
done 

ale vygenerovala chybu test.sh: line 5: ./test.py: Permission denied.

Jak tedy čtu řádek po řádku, protože si myslím, že v současné době celý řádek naráží.

Požadovaný výstup:

./test.py
./test1.py
./out1
./test.sh
./out
./out2
./hello
50
RanRag

Je chyba, potřebujete < <(command) not <<<$(command)

< <( ) je Substituce proces , $() je substituce příkaz a <<< je zde řetězec .

59
Gilles Quenot

Všimněte si, že nic nebrání tomu, aby názvy souborů obsahovaly znaky nového řádku. Kanonický způsob, jak spustit příkaz pro každý soubor nalezeno podle hledání, je.

find . -type f -exec cmd {} \;

A pokud chcete dělat věci v bash:

find . -type f -exec bash -c '
  for file do
    something with "$file"
  done' bash {} +

Kanonický způsob, jak vyvolat příkaz „read“ ve skriptech (pokud nechcete, aby na vstupu provedl další zpracování), je:

IFS= read -r var

-r znamená zastavit read ze zvláštního zacházení se znaky zpětného lomítka (jako únikový znak pro oddělovače a nový řádek) a IFS = nastavit seznam oddělovačů na prázdný řetězec pro read (jinak pokud jakýkoli znak mezery byl v tomto seznamu, budou odříznuty od začátku a konce vstupu).

Používání smyček ve skořápce je obvykle špatný nápad (ne to, jak se děje ve skořápce, kde necháte několik nástrojů pracovat společně a souběžně na úkolu, spíše než spouštět jeden nebo více nástrojů stokrát za sebou).

14
Stéphane Chazelas

Pokud chcete použít potrubí, není třeba substituce příkazů:

find . -type f |
while read -r line
do
    echo "$line"
done

Přestože, jak již bylo uvedeno, v případě find byste s jeho -exec možnost.

0