[opensuse] Back to the basics (bash)
Hi!, anybody can tell me why using "[]" sustitution for file listing works ciro@roamer:/tmp> ls -ld [123]b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 1b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 2b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 3b But for file creation it doesn't? ciro@roamer:/tmp/bash> mkdir [123]dir ciro@roamer:/tmp/bash> touch [123].file ciro@roamer:/tmp/bash> ls -l total 4 drwxr-xr-x 2 ciro users 4096 ago 11 17:04 [123]dir -rw-r--r-- 1 ciro users 0 ago 11 17:04 [123].file Regards, -- Ciro Iriarte http://cyruspy.wordpress.com -- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 08/11/2013 11:04 PM, Ciro Iriarte wrote:
Hi!, anybody can tell me why using "[]" sustitution for file listing works
That's because of shell globbing.
ciro@roamer:/tmp> ls -ld [123]b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 1b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 2b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 3b
Here, the files 1b, 2b, 3b exist, so the shell can glob them and pass them to ls(1).
But for file creation it doesn't?
ciro@roamer:/tmp/bash> mkdir [123]dir ciro@roamer:/tmp/bash> touch [123].file ciro@roamer:/tmp/bash> ls -l total 4 drwxr-xr-x 2 ciro users 4096 ago 11 17:04 [123]dir -rw-r--r-- 1 ciro users 0 ago 11 17:04 [123].file
Here, the glob pattern (incidentally!) doesn't match a glob because the files didn't exist yet. Therefore, the shell passes them as string to mkdir(1) and touch(1). In the case you're unsure, try adding "echo" in front of the commands. By this, you'll see what the shall will pass to the commands. In your case, it should look like that: $ echo ls -ld [123]b ls -ld 1b 2b 3b $ echo mkdir [123]dir mkdir [123]dir Have a nice day, Berny -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
2013/8/11 Bernhard Voelker <mail@bernhard-voelker.de>:
On 08/11/2013 11:04 PM, Ciro Iriarte wrote:
Hi!, anybody can tell me why using "[]" sustitution for file listing works
That's because of shell globbing.
ciro@roamer:/tmp> ls -ld [123]b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 1b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 2b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 3b
Here, the files 1b, 2b, 3b exist, so the shell can glob them and pass them to ls(1).
But for file creation it doesn't?
ciro@roamer:/tmp/bash> mkdir [123]dir ciro@roamer:/tmp/bash> touch [123].file ciro@roamer:/tmp/bash> ls -l total 4 drwxr-xr-x 2 ciro users 4096 ago 11 17:04 [123]dir -rw-r--r-- 1 ciro users 0 ago 11 17:04 [123].file
Here, the glob pattern (incidentally!) doesn't match a glob because the files didn't exist yet. Therefore, the shell passes them as string to mkdir(1) and touch(1).
In the case you're unsure, try adding "echo" in front of the commands. By this, you'll see what the shall will pass to the commands. In your case, it should look like that:
$ echo ls -ld [123]b ls -ld 1b 2b 3b
$ echo mkdir [123]dir mkdir [123]dir
Have a nice day, Berny
Thanks Berny, but why [] doesn't work in both cases like {}?, {} works for file listing and for file creation... That's why I was expecting [] to work the same way (my bad?) Regards, -- Ciro Iriarte http://cyruspy.wordpress.com -- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Ciro Iriarte said the following on 08/11/2013 05:29 PM:
Thanks Berny, but why [] doesn't work in both cases like {}?, {} works for file listing and for file creation... That's why I was expecting [] to work the same way (my bad?)
The "[]" is pattern matching for a set of characters The "{}" is enumeration for a set of file names You would have to do ls {1,2,3)b to match files 1b, 2b and 3b. Enumeration means that the names are generated by shell expansion regardless of whether the files exist or not. So you might get $ ls {1,2,3}b ls: cannot access 1b: No such file or directory ls: cannot access 3b: No such file or directory 2b if only "2b" existed. Or worse mkdir {1,2,3}b mkdir: cannot create directory ‘2b’: File exists and now $ ls -ld {1,2,3}b drwxr-xr-x 1 anton users 0 Aug 11 17:35 1b -rw-r--r-- 1 anton users 0 Aug 11 17:34 2b drwxr-xr-x 1 anton users 0 Aug 11 17:35 3b -- How long did the whining go on when KDE2 went on KDE3? The only universal constant is change. If a species can not adapt it goes extinct. That's the law of the universe, adapt or die. -- Billie Walsh, May 18 2013 -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Aug 11, 2013, at 23:29 , Ciro Iriarte wrote:
Thanks Berny, but why [] doesn't work in both cases like {}?, {} works for file listing and for file creation... That's why I was expecting [] to work the same way (my bad?)
That would probably be a bad idea, since things like [a-z] would become pretty useless (or you could only use them with commands that generate errors when encountering non-existent file names). A. -- Ansgar Esztermann DV-Systemadministration Max-Planck-Institut für biophysikalische Chemie, Abteilung 105
On 8/11/2013 5:04 PM, Ciro Iriarte wrote:
Hi!, anybody can tell me why using "[]" sustitution for file listing works
ciro@roamer:/tmp> ls -ld [123]b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 1b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 2b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 3b
But for file creation it doesn't?
ciro@roamer:/tmp/bash> mkdir [123]dir ciro@roamer:/tmp/bash> touch [123].file ciro@roamer:/tmp/bash> ls -l total 4 drwxr-xr-x 2 ciro users 4096 ago 11 17:04 [123]dir -rw-r--r-- 1 ciro users 0 ago 11 17:04 [123].file
Regards,
[123] is a globbing pattern like * is. Globbing only expands to existing files that match the pattern, if any. If only one or two of the possible files exist, then the pattern will only expand to those one or two files, not all 3. If none exist then no expansion or substitution occurs and you get the literal string [123]. In the case of creating new files, since they may or may not exist, or maybe some exist and not all, you don't want globbing, you want string manipulation. You want to be able to write some kind of shorthand that expands to the final string you want, as a plain string manipulation, not trying to find any existing files. mkdir {1,2,3}dir touch {1,2,3}.file Note these are all somewhat shell specific. These are simple enough that they work in pretty much any version of bash no matter how old, but may not work in some other shells like ash used in initrd's or dsh (debian) or /bin/sh on other unix systems besides linux. Also note that it's up to you to verify that commands like mkdir and touch can even take multiple target arguments at the same time on one command line. They both can, at least on linux, so these commands would work. But in other cases, or if the expanded list were longer than about 4kb, you would have to learn about xargs. Also use echo to test potentially risky expansions like this to make sure it will do what you think it will do before you let real commands actually try to do stuff. dev1:oh7:~ $ echo [123]foo [123]foo dev1:oh7:~ $ echo {1,2,3}foo 1foo 2foo 3foo -- bkw -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Thanks! 2013/8/13 Brian K. White <brian@aljex.com>:
On 8/11/2013 5:04 PM, Ciro Iriarte wrote:
Hi!, anybody can tell me why using "[]" sustitution for file listing works
ciro@roamer:/tmp> ls -ld [123]b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 1b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 2b drwxr-xr-x 2 ciro users 4096 ago 10 16:22 3b
But for file creation it doesn't?
ciro@roamer:/tmp/bash> mkdir [123]dir ciro@roamer:/tmp/bash> touch [123].file ciro@roamer:/tmp/bash> ls -l total 4 drwxr-xr-x 2 ciro users 4096 ago 11 17:04 [123]dir -rw-r--r-- 1 ciro users 0 ago 11 17:04 [123].file
Regards,
[123] is a globbing pattern like * is. Globbing only expands to existing files that match the pattern, if any. If only one or two of the possible files exist, then the pattern will only expand to those one or two files, not all 3. If none exist then no expansion or substitution occurs and you get the literal string [123].
In the case of creating new files, since they may or may not exist, or maybe some exist and not all, you don't want globbing, you want string manipulation.
You want to be able to write some kind of shorthand that expands to the final string you want, as a plain string manipulation, not trying to find any existing files.
mkdir {1,2,3}dir touch {1,2,3}.file
Note these are all somewhat shell specific. These are simple enough that they work in pretty much any version of bash no matter how old, but may not work in some other shells like ash used in initrd's or dsh (debian) or /bin/sh on other unix systems besides linux.
Also note that it's up to you to verify that commands like mkdir and touch can even take multiple target arguments at the same time on one command line. They both can, at least on linux, so these commands would work. But in other cases, or if the expanded list were longer than about 4kb, you would have to learn about xargs.
Also use echo to test potentially risky expansions like this to make sure it will do what you think it will do before you let real commands actually try to do stuff.
dev1:oh7:~ $ echo [123]foo [123]foo dev1:oh7:~ $ echo {1,2,3}foo 1foo 2foo 3foo
-- bkw
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-- Ciro Iriarte http://cyruspy.wordpress.com -- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
participants (5)
-
Anton Aylward
-
Bernhard Voelker
-
Brian K. White
-
Ciro Iriarte
-
Esztermann, Ansgar