Speciális karakter probléma bash scriptben

Sziasztok!

Adott egy egyszerű script, ami annyit tesz, hogy egy adott könyvtárban megkeresi hol helyezkedik el az argumentumként megadott fájl, majd attól a fájltól kezdve az összeset átadja az mplayernek lejátszásra.
Ez több darabból álló filmeknél, sorozatoknál jól jön, csak a speciális karakterekkel akad gondja, jelen esetben a ' jellel.
A szkript:

#!/bin/sh
pkill -19 rtorrent
cd "$(dirname "$1")"
file=$(echo $(basename "$1")|sed 's/ /\\ /g'|sed 's/\[/\\\[/g'|sed 's/\]/\\\]/g')
ls|grep -A 100 "$file"|sed 's/ /\\ /g'|xargs sudo nice -n -10 mplayer -fs
pkill -18 rtorrent

Hibaüzenet: "xargs: pár nélküli egyszeres idézőjel; alapértelmezésben az idézőjelek speciálisak az xargs számára, hacsak nem használja a -0 kapcsolót"
Ha a "file" sorhoz hozzárakok egy plusz sed-es részt(sed "s/\'/\\\'/g"), akkor sem védi le, ha "xargs -0"-t írok, akkor a többi fájlt sem játssza le.
Van egy hasonló script a mocp-hoz, de annál is ugyanez a probléma.

Hogyan lehetne megoldani, hogy minden speciális karaktert lekezeljen a fájl nevekben?

Hozzászólások


cd "$(dirname "$1")"
match=$(basename "$1")
find | grep grep -A 100 "$match" |
while read file ; do sudo nice -n -10 mplayer -fs "$file"; done

Sajnos nem jó.
Először is gondolom nem kell 2 grep, csak elírtad(legalábbis úgy nem csinált semmit).
Ha azt javítom, akkor elkezdi lejátszani a fájlt, de azonnal ki is lép:

A: 0.3 V: 0.0 A-V: 0.262 ct: 0.001 2/ 2 ??% ??% ??,?% 0 0
===== PAUSE =====

MPlayer interrupted by signal 11 in module: key_events
- MPlayer crashed by bad usage of CPU/FPU/RAM.
Recompile MPlayer with --enable-debug and make a 'gdb' backtrace and
disassembly. Details in DOCS/HTML/en/bugreports_what.html#bugreports_crash.
- MPlayer crashed. This shouldn't happen.
It can be a bug in the MPlayer code _or_ in your drivers _or_ in your
gcc version. If you think it's MPlayer's fault, please read
DOCS/HTML/en/bugreports.html and follow the instructions there. We can't and
won't help unless you provide this information when reporting a possible bug.
[ This binary of MPlayer in Debian is currently compiled with
'--enable-debug'; the debugging symbols are in the package
'mplayer-dbg'.]

Ha olyan fájlt akarok lejátszani aminek a nevében nincs speciális karakter, akkor is ugyanez van, csak ilyenkor az utána következő fájlokat is megpróbálja lejátszani s vagy ugyanezzel a hibával leáll vagy ha szóköz van a fájl névben akkor eleve el sem kezdi játszani, mert nem tudja, hogy meddig számít egy fájlnak és kiírja, hogy "File not found."
Ha nem a scriptből indítom el, akkor tökéletesen viszi őket.

Aki speciális karaktereket rak fájlnevekbe, az szerencsés ember nem lehet...

Szerintem a legtisztább megoldás, ha vannak ilyesmi speciális karakterek (aposztróf, szóköz stb.) a fájlnevekben, hogy csupa olyan progit használsz, ami nullás byte-tal választja el az input mezőket, nem újsorral.

find ... -print0 | grep -z ... | xargs -0 ...

sed elfelejtve. Ha egyszintű (nem rekurzív) listázást akarsz, akkor a find-nak -maxdepth 1 vagy valami hasonló opciója segít, vagy kézzel kábé így: for i in *; do printf '%s\000' "$i"; done. Esetleg, ha tudod hogy egyik fájlnév sem tartalmaz newline-t :), akkor a grep-ig maradhat a te megoldásod, onnan pedig tr '\n' '\0' | xargs -0 ...

Ez a tökéletes megoldás, köszönöm!

Épp írni akartam, hogy egmont javaslata majdnem 100%-ig bevált, csak ha [] karakterek vannak a fájlnévben akkor a grep hibát jelez, de a -F kapcsolóval ez megszűnt.
Még egyszer nagyon köszönöm mindenkinek a segítséget és a tanácsokat, erre magamtól soha nem jöttem volna rá.

Lenne egy kérdésem egy másik scriptel kapcsolatban is.
Ez annyit csinál, hogy a megadott könyvtárban megkeresi az összes .srt fájlt és ellenőrzi őket a subcheck.pl script segítségével.

#!/bin/sh
while getopts ":cf" kapcs
do
case $kapcs in
"c")
for i in "$@"; do
subcheck.pl -c 40 -b -i "$i"
done
;;
"f")
for i in "$@"; do
find "$i" -iname "*.srt" -print0|xargs -0 srtcheck -c
done
;;
esac
done
exit 0

A használata pedig "script -f könyvtár_név", az egyetlen szépséghibája, hogy önmagát kell meghívni egy másik kapcsolóval, mivel a "-f" opciónál található parancs végére nem lehet egy ciklust megadni csak futtatható fájlt, ha definiálok egy funkciót az sem jó, mert a xargs nem tudja értelmezni.
googlizás során a legtöbb helyen azt ajánlották, hogy egy másik szkriptet hívjunk meg a xargs-al, de furcsállanám ha egy ilyen egyszerű feladatra 2 script kellene.
Az egyetlen érdekes találat ez volt: http://www.linux.net.nz/pipermail/nzlug/2007-April/008541.html
Csak azt nem értem mit ért a "while read FILENAME" alatt.
Valahogy lehet hivatkozni a pipe által átadott értékekre, mondjuk úgy mint a bash szkripteknél a "$@" változóval?

Mert ha nem a "xargs -0"-val indítom a subcheck.pl-t, akkor mindig baja van a speciális karakterekkel.
Pl:
#!/bin/sh
files=`find "$1" -iname "*.srt" -print0`
for i in "$files"; do
subcheck.pl -c 40 -b -i "$i"
done

Ha a files-nál az van, hogy "find "$1" -iname "*.srt" -print0|xargs -0 ls" akkor sem jó.

Van valami egyszerűbb módszer amivel egy scripten belül megoldható, mindenféle kapcsolókkal való játszadozás nálkül?

A GNU-s find (find (GNU findutils) 4.4.0) köhög a paraméterek sorrendjére (a könyvtárban normál fájlok nem, csak további alkönyvtárak vannak), mondjuk úgy, jogosan...:


$ find . -type f -maxdepth 1
find: warning: you have specified the -maxdepth option after a non-option argument -type, 
but options are not positional (-maxdepth affects tests specified before it as well as 
those specified after it).  Please specify options before other arguments.

$ ls -l
total 0
drwxrwxrwx+  6 zeller zeller 0 May 22  2008 qka
drwxrwxrwx+ 23 zeller zeller 0 Jan  4 19:40 qka1
drwxrwxrwx+  6 zeller zeller 0 May 24  2005 tmp