You are not logged in.
Hello,
I need to make a list of all files inside a directory.
Let's say file1 file2 file3.
When I use:
ls > my_list
I end up with this content inside my_list
file1
file2
file3
my_list
How come my_list appears in the file since it does not yet exist when ls is invoked?
Last edited by raphaelabb (2024-03-25 16:54:03)
Offline
https://www.gnu.org/software/bash/manua … tions.html says the resulting destination for the output is opened for writing before the left side operation, so my_list is created before ls is performed.
a man a plan a canal panama
Offline
Parsing the output of ls is usually a bad idea: https://mywiki.wooledge.org/ParsingLs
Better:
$ mkdir test ; cd $_
$ touch a b c d e
$ for i in * ; do echo "$i" >> my_list ; done
$ cat my_list
a
b
c
d
e
$
Last edited by Head_on_a_Stick (2024-03-24 20:26:25)
Para todos todo, para nosotros nada
Offline
I see. But why
ls * > my_list
does not include my_list inside the created file?
Offline
Because the glob is parsed by the shell not by ls - this command line parsing is done before the redirection is handled to create the "my_list" file.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
https://www.gnu.org/software/bash/manua … nsion.html says the asterisk is replaced by a list of filenames, so in effect here you are listing explicitly the filenames you wish to have operated on by ls and placed into my_list. This replacement happens first in the shell order of operations.
I typed too slow...
Last edited by gxt25 (2024-03-24 20:50:14)
a man a plan a canal panama
Offline
$ for i in * ; do echo "$i" >> my_list ; done
printf '%s\n' * >my_list
Offline
This thread is a perfect example of the problem of learning some "rule" without understanding why the rule exists. The OP isn't parsing the output of ls, they're just sending it to a file. And as for all these "alternatives" to `ls`, they don't do anything better than ls itself. Stop over-correcting ... incorrectly.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
a) put the my_list file outside of the scanned directory
ls > ../my_list
b) let ls ignore the filelist
ls --ignore my_list > my_list
c) use tee to generate my_list
ls | tee my_list
Offline
This thread is a perfect example of the problem of learning some "rule" without understanding why the rule exists.
To some extent.
I need to make a list of all files inside a directory.
and while there's no indication of the reasons for that "need", ls will not necessarily do that - it could be a random alias or function¹ or suffer from the "file contains newline" condition.
So to get a (probably) desired and somewhat predictable output (*esp* outside a script) you'd start by "command ls" and somehow put "-b" in there.
¹column is about to get its ANSI bug fixed at which point the default "ls" will ellipt long filenames here
Offline
GerBra, `ls * > my_list` is far simpler and has already been noted in the thread.
Seth, if were looking for portable usage, the -b flag is not a good idea. That is a non-posix extension.
Last edited by Trilby (2024-03-25 13:08:28)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
`ls * > my_list` is far simpler and has already been noted in the thread.
Hey, shell globbing is a lot more expensive ;-)
mkdir /tmp/tt
cd /tmp/tt
$ touch file{1..10000}
$ time ls --ignore my_list > my_list
real 0m0,015s
user 0m0,011s
sys 0m0,004s
$ time ls * > my_list
real 0m0,047s
user 0m0,022s
sys 0m0,025s
And using --ignore foobar will never include foobar in the generated filelist, even on multiple runs (but then the ls output is not exactly what it should be...<g>)
Duck and away ;-)
Btw: using the Pipe with tee doesn't work on a lot of entities, at some time the my_list file would be created by tee and get listed by ls
Offline
The list of files is not to be used for further programming, it's just for me to keep track of certain files I will have to back up in my external HDD once I get it back.
So
ls * > my_list
is the simplest way in that case.
Thank you.
Offline
GerBra, globbing in *your shell* is slow
(bash)$ time ls * > my_list
real 0m0.044s
user 0m0.020s
sys 0m0.023s
(bash)$ time ls --ignore my_list > my_list
real 0m0.018s
user 0m0.004s
sys 0m0.014s
(bash)$ exit
(a real shell)$ time ls * >| my_list
real 0m 0.02s
user 0m 0.00s
sys 0m 0.01s
EDIT: in fact, globbing is faster in my shell than letting ls figure it out:
$ time ls >| my_list
real 0m 0.03s
user 0m 0.02s
sys 0m 0.01s
Last edited by Trilby (2024-03-25 17:50:58)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Though even in A SHell "ls *" will handle directories wrong™ and should™ be lucy in the sky with diamonds, no?
Offline
What do you mean by "wrong"? EDIT: if you mean `ls *` would list contents of subdirectories, then just add the -d flag.
Last edited by Trilby (2024-03-26 01:11:51)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
ls * goes into direct sub-directories.
and ls -R is recursive, as noticed we don't know if ls is an alias and how it's configured.
Offline
then just add the -d flag
https://en.wikipedia.org/wiki/Lucy_in_t … SD_rumours
Depending on
keep track of certain files I will have to back up
one also might want to put an "-A" in there, resp. "ls -d .* *" while the exact behavior of the globbing depends on the set shell options.
Offline