Best way to reimplement Unix pipes
-
I really don't know what the person behind this was thinking:
LIST_FILES=`ls $SOME_DIR`
for files in $LIST_FILES; do
echo $files >> foo.txt
doneThe worst part is that it doesn't have into account filenames with blank spaces.
-
Isn't Unix aptly described as a series of pipes?
-
Seems they were after this:
ls $SOME_DIR >> foo.txt
Did they think ">>" only works with echo?
-
Maybe they just wanted to mess up the space characters.
-
Obviously they should have done:
ls $SOME_DIR | xargs -n 1 echo >> foo.txt
-
-
@ubersoldat said:
The worst part is that it doesn't have into account filenames with blank spaces.
Technically it only messes up spaces if there are multiple space characters in a row or if there are non-space whitespace characters.
-
@dhromed said:
Isn't Unix aptly described as a series of pipes?
Aren't your neigborhood "pool parties" aptly described as a series of hoses?
-
-
@ubersoldat said:
The worst part is that it doesn't have into account filenames with blank spaces.
Huh?
-
@blakeyrat said:
@ubersoldat said:
The worst part is that it doesn't have into account filenames with blank spaces.
Huh?
Stupid Windozo lo$er, you probably didn't even realize filenames could have spaces or new-lines or BEL characters in them. See, Unix shells do word splitting. So if the filename has a space, that gets saved to the variable "files". Now, he's calling doing 'echo $files'. The shell substitutes $files for the content of the variable, then it does word-splitting, so if the variable files contains whitespace, the shell splits that whitespace into individual arguments. If your filename is "foo bar.txt", then your shell calls echo with two arguments: 'foo' and 'bar.txt'. If it's only a single space, no biggie, because echo will put a space between each argument it echos out. However, if your filename is "foo bar.txt" (two spaces, CS might eat that and only show one) or "foo\tbar.txt" or "foo\nbar.txt", the shell will split all of those into two arguments for echo, which will echo them out with one space between them.
In short, you should always quote strings when used in arguments. Quoting treats the string as a single argument, keeping it from doing word-splitting. So 'echo "$files" >> foo.txt' would have been the proper way.
-
@morbiuswilters said:
In short, you should always quote strings when used in arguments. Quoting treats the string as a single argument, keeping it from doing word-splitting. So 'echo "$files" >> foo.txt' would have been the proper way.
No! Bad! Stop lying to Windows users to amuse yourself. The problem is actually using [code]ls[/code] with [code]for ... in[/code] instead of just using a glob directly:bstorer@Heimdall ~/gay morb $ ls morb is a fag
bstorer@Heimdall ~/gay morb
$ LIST_FILES=ls $SOME_DIR
bstorer@Heimdall ~/gay morb
$ for files in $LIST_FILES; do echo "$files"; done
morb
is
a
fagbstorer@Heimdall ~/gay morb
$ for files in *; do echo $files; done
morb is a fag
-
I <3 U
-
@bstorer said:
$ ls
morb is a fagHmm.. using directory ordering rather than alphabetical? I hate you.
@bstorer said:
bstorer@Heimdall ~/gay morb
$ for files in *; do echo $files; done
morb is a fagecho should be inserting a newline after each of those. Either your echo is non-standard or you made this whole thing up to make me look like a fag.
-
@morbiuswilters said:
You misunderstand me. Let me offer a clearer example:echo should be inserting a newline after each of those. Either your echo is non-standard or you made this whole thing up to make me look like a fag.
[~/gay morb]$ ls -lb total 0 -rw-rw-r-- 1 bstorer pg588160 0 Mar 24 22:03 i\ love\ you\ morb -rw-rw-r-- 1 bstorer pg588160 0 Mar 24 21:58 morb\ is\ a\ fag -rw-rw-r-- 1 bstorer pg588160 0 Mar 24 22:02 morb\ loves\ the\ cock
[~/gay morb]$ for file in
ls *
; do echo "$file"; done
i
love
you
morb
morb
is
a
fag
morb
loves
the
cock[~/gay morb]$ for file in *; do echo $file; done
i love you morb
morb is a fag
morb loves the cock
See what I'm talking about? No amount of quoting in the [code]echo[/code] command will make it work because the results of the backtick expansion are split on whitespace anyway. Now, admittedly, you're right, [code]echo[/code] should still have its argument quoted:
[~/gay morb]$ touch morb\'s\ \ withered\ \ penis
[~/gay morb]$ ls -lb
total 0
-rw-rw-r-- 1 bstorer pg588160 0 Mar 24 22:03 i\ love\ you\ morb
-rw-rw-r-- 1 bstorer pg588160 0 Mar 24 21:58 morb\ is\ a\ fag
-rw-rw-r-- 1 bstorer pg588160 0 Mar 24 22:02 morb\ loves\ the\ cock
-rw-rw-r-- 1 bstorer pg588160 0 Mar 24 22:05 morb's\ \ withered\ \ penis[~/gay morb]$ for file in *; do echo $file; done
i love you morb
morb is a fag
morb loves the cock
morb's withered penis[~/gay morb]$ for file in *; do echo "$file"; done
i love you morb
morb is a fag
morb loves the cock
morb's withered penis
-
@bstorer said:
You misunderstand me. Let me offer a clearer example:
I feel there is something insinuated by your code... but I can't quite put my finger on it.
-
@Thief^ said:
Seems they were after this:
ls $SOME_DIR >> foo.txt
Did they think ">>" only works with echo?
Probably. Similar to how some people always do
cd \
cd some\other\dir
-
@dhromed said:
I feel there is something insinuated by your code... but I can't quite put my finger on it.
I don't think you want to put your finger on it... unless you're into that kind of thing of course.
-
/tmp/x$ ls -l total 0 -rw-r--r-- 1 ais523 ais523 0 2010-03-25 13:01 foo.txt -rw-r--r-- 1 ais523 ais523 0 2010-03-25 13:01 t 1 -rw-r--r-- 1 ais523 ais523 0 2010-03-25 13:01 t 2 -rw-r--r-- 1 ais523 ais523 0 2010-03-25 13:01 t3 /tmp/x$ env IFS="`printf "\n"`" X="`ls`" sh -c 'for a in $X; do echo "$a"; done'
foo.txt t 1 t 2 t3The technique written in the code could work; what's necessary is setting (temporarily, I hope!) IFS to newline rather than space so that for doesn't try to split on spaces, and quoting the backticks so that they don't try to split on spaces either. Of course, this is ridiculous.
TRWTF is that the correct way to do what that code was probably meant to do is "ls $SOMEDIR >> foo.txt" (or maybe even "ls $somedir > foo.txt", depending exactly on what the code meant to do). The clearest way to do what it actually does (replacing characters in $IFS with newlines in ls's output, squeezing duplicates), if that was intended behaviour, is probably like this:
/tmp/x$ ls $SOMEDIR | tr -s "$IFS" "[\n*]" >> foo.txt
/tmp/x$ cat foo.txt
foo.txt
t
1
t
2
t3although even that doesn't allow for the fact that $SOMEDIR might be the current directory and foo.txt might not already exist (in which case, foo.txt might be shown in the listing with this method when it definitely wouldn't with the other method, depending on whether the shell creates the file faster or slower than ls runs).
-
@morbiuswilters said:
@bstorer said:
$ ls
morb is a fagHmm.. using directory ordering rather than alphabetical? I hate you.
So you prefer "a fag is morb"? I don't find it much of an improvement.
-
@ubersoldat said:
The worst part is that it doesn't have into account filenames with blank spaces.
What about non-blank spaces?
-
@Adriano said:
@morbiuswilters said:
Thinks it's fucking great, Yoda does.@bstorer said:
$ ls
morb is a fagHmm.. using directory ordering rather than alphabetical? I hate you.
So you prefer "a fag is morb"? I don't find it much of an improvement.