BASH, why is so F***king difficult
Giorgos Keramidas
keramida at ceid.upatras.gr
Mon Nov 12 23:16:39 EET 2007
On 2007-11-12 20:44, Harris Kosmidhs <hkosmidi at laboratorium.gr> wrote:
> Πάντα με παίδευε το bash. Αλλά τώρα έχω μπροστά μου και manual και πάλι
> δε βγάζω άκρη...
>
> Έχω σε ένα φάκελο τους παρακάτω φακέλους:
> Cocteau Twins__Milk_and_kisses
> Muse-Black.Holes.and.Revelations
> Nick_Cave__The First Born Is Dead
> PinkFloyd__Momentary_lapse_of_reason
> PorcupineTree__Yellow_Hedgerow_Dreamscape
> Radiohead__In_rainbows
> RichardWright__Wet_dream
> Tuxedomoon__Divine
>
> Και το εξής script:
>
> #!/bin/bash
>
> until [ -z "$1" ]
> do
> dir="$1 "
> #chmod 755 $dir
> if [ -x ${dir} ];then
> echo $dir
> fi
>
> shift
> done
>
> Το τρέχω και μου βγάζει:
> hkosmidi at desktop:~/mp3$ ./convert.sh *
> ./convert.sh: line 7: [: Cocteau: binary operator expected
> convert.sh
> convert.sh~
> Muse-Black.Holes.and.Revelations
> ./convert.sh: line 7: [: too many arguments
> PinkFloyd__Momentary_lapse_of_reason
> PorcupineTree__Yellow_Hedgerow_Dreamscape
> Radiohead__In_rainbows
> RichardWright__Wet_dream
> Tuxedomoon__Divine
>
> Γιατί; Το dir το όρισα με τα κενά μέσα κάνοντας quoting με "".
> Αν κάνω if [ -x "${dir}" ];then τότε δεν τυπώνεται τίποτε.
Γιατί δεν είσαι προσεκτικός όταν κάνεις χρήση του ${dir}:
Διάβασε το παρακάτω παράδειγμα, και βρες μόνος σου τι έκανα διαφορετικό:
keramida at kobe:/home/keramida/tmp/kot$ cat -n foo.sh
1 #!/usr/local/bin/bash
2 until [ -z "$1" ]; do
3 arg="$1"
4 echo "${arg}"
5 if test -f "${arg}"; then
6 echo "${arg} ok"
7 fi
8 shift
9 done
keramida at kobe:/home/keramida/tmp/kot$ ls -ld *' '*
-rw-rw-r-- 1 keramida users - 0 Nov 12 23:06 alpha one
-rw-rw-r-- 1 keramida users - 0 Nov 12 23:06 beta two
keramida at kobe:/home/keramida/tmp/kot$ sh foo.sh *
alpha one
alpha one ok
beta two
beta two ok
foo.sh
foo.sh ok
keramida at kobe:/home/keramida/tmp/kot$
> Τι στο καλό φταίει; Γιατί είναι τόσο δύσκολο να διαχειριστεί το bash
> τα κενά στα filenames;
Δεν είναι. Απλά θέλει προσοχή.
Κι επιτέλους, γιατί γράφεις σε bash αν σε τσαντίζει;
Γράψε σε Perl, και ενεργοποίησε όλα τα 'taint checks' ώστε να έχεις τον
απόλυτο έλεγχο του τι θεωρείται 'valid' argument:
keramida at kobe:/home/keramida/tmp/kot$ cat -n foo.pl
1 #!/usr/bin/perl -Tw
2
3 foreach my $arg (@ARGV) {
4 my $fname = undef;
5 if ($arg =~ m/([\w\s]*)/) {
6 # Untaint argument.
7 $fname = $1;
8 }
9 if (defined($fname)) {
10 print "arg ${fname}\n";
11 }
12 }
keramida at kobe:/home/keramida/tmp/kot$ ./foo.pl *' '*
arg alpha one
arg beta two
keramida at kobe:/home/keramida/tmp/kot$
Γράψε σε Python, για να μπορείς να έχεις αντίστοιχα features, και ίσως
ελαφρώς πιο 'readable' κώδικα, αν προτιμάς αυτό το στυλ:
keramida at kobe:/home/keramida/tmp/kot$ cat -n foo.py
1 #!/usr/bin/env python
2
3 import re
4 import sys
5
6 for name in sys.argv[1:]:
7 k = re.match('([\w\s]*)', name)
8 if k:
9 print k.string
keramida at kobe:/home/keramida/tmp/kot$ ./foo.py *' '*
alpha one
beta two
keramida at kobe:/home/keramida/tmp/kot$
Ο,τι κι αν διαλέξεις όμως, πάψε να γκρινιάζεις :P
More information about the Linux-greek-users
mailing list