Bash is removing commands in while?

2019-08-04 04:14发布

问题:

I really dont understand why this is happening, bash seems to remove commands while running in a while loop. I have the following script:

adb shell ls /foo/bar | while read file 
do
    folder="/foo/bar/$file"                                                                                                                                                                                                                                                    
    adb pull $folder download
done

when i run the command seperatly, it works great. But wen i run it like this, i get the following output:

' does not existfoo/bar/filesdfsdf.sdf

for every file in /foo/bar.

SO i tried to give me the command back as string, i changed to echo "adb pull $folder download" and got the following output:

 download/foo/bar/fileasdfs.sdf

for each line. It seems that bash does something with the string and replaces some stuff here... If i use ', so no bash replacement would occur, i get the correct output.

whats happening here?

EDIT: I figured out that not while is directly broken, its the adb shell command what echoes a CRLF on every line end. if i use

adb shell ls /foo/bar | tr -d '\015' | while read file 
do
    folder="/foo/bar/$file"                                                                                                                                                                                                                                                    
    adb pull $folder download
done

it works! But why is bash so allergic to CRLF? And why its deletes comnmands?

回答1:

I don't know what you mean by "Why does while not allow CR?". The correct question is "What does read do with CR?". Unless stating otherwise, read uses CR for parameter splitting. Look in your bash-manual for the variable IFS, and have a look at the -d option to read.

Example:

bos:$ echo foo bar gazonk | while read x ; do echo $x ; done
foo bar gazonk

Here, the CR acts as (default) delimiter for read. Now, say you want to split the read at every word, then you would use -d " " (setting SPC as delimiter):

$ echo foo bar gazonk hello 123 | while read -d " " x ; do echo $x ; done
foo
bar
gazonk
hello

The backside here is that the last parameter (123) is not output because it does not end with a delimiter. Think of the delimiter as grabbing everything LEFT of it, up to but not including the next delimiter. Since "123" does not end with a delimiter, the last delimiter is between "hello" and "123", and - thus - what's grabbed is "hello" because it has a delimiter to left and to right of it.



标签: bash replace