Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2012-05-14 13:20:54

  Minio - Użyszkodnik

Minio
Użyszkodnik
Skąd: Poznań, Polska
Zarejestrowany: 2007-12-22
Serwis

[shell] pętla i problem ze spacjami w nazwach plików

Chcę w shellu skonstruować listę plików w katalogu, która następnie zostanie przekazana innemu programowi. Problemem są spacje (i pewnie inne białe znaki).
Najprościej chyba będzie pokazać sam kod. Tak więc pliki są takie:

Kod:

$ ls -1 /tmp/dir/
another one
some file

Program zaś taki:

Kod:

for filepath in /tmp/dir/* ; do
   name="$(basename "$filepath")"
   FILES="$FILES $filepath $name"
done

FILE=$(zenity --list --title="Wybierz plik" --hide-column=1 --column="sciezka" --column="Profil" $FILES)
echo "$FILE"

Zenity potrzebuje pary argumentów — najpierw ścieżki (to mi zwróci na wyjściu), potem nazwy pliku (to wyświetli). Niestety interpretuje spacje w nazwach plików jako koniec pierwszego elementu w parze, w związku z czym wyświetla coś takiego.

Póki co poradziłem sobie przy pomocy eval (kod na końcu wiadomości), ale nie podoba mi się to rozwiązanie. Można to jeszcze zrobić jakoś inaczej, bardziej elegancko? Wszelkie pomysły mile widziane.

Kod:

for filepath in /tmp/dir/* ; do
   name="$(basename "$filepath")"
   FILES="$FILES \"$filepath\" \"$name\""
done
FILE=$(eval zenity --list --title=\"Wybierz plik\" --hide-column=1 --column=\"sciezka\" --column=\"Profil\" $FILES)
echo "$FILE"

Efekt (oczekiwany)

Offline

 

#2  2012-05-14 14:05:30

  azhag - Admin łajza

azhag
Admin łajza
Skąd: Warszawa
Zarejestrowany: 2005-11-15

Re: [shell] pętla i problem ze spacjami w nazwach plików

Mniemam (w sumie nie sprawdzałem, ale podobny przypadek przerabiałem kiedyś), że problemem jest właśnie to, że używasz zmiennej w poleceniu. Powłoka czasami się trochę gubi przy interpretowaniu zmiennej jako argumentów (stąd właśnie eval) — jakbyś ręcznie (przynajmniej ja tak miałem w omawianym przypadku) wpisał zawartość $FILES w poleceniu (bądź zastosował `echo $FILES` ;)), to mogłoby się wykonać zgodnie z oczekiwaniami.

Obawiam się, że musisz zacisnąć zęby i po prostu korzystać z eval.


Błogosławieni, którzy czynią FAQ.
opencaching :: debian sources.list :: coś jakby blog :: polski portal debiana :: linux user #403712

Offline

 

#3  2012-05-14 22:02:21

  Minio - Użyszkodnik

Minio
Użyszkodnik
Skąd: Poznań, Polska
Zarejestrowany: 2007-12-22
Serwis

Re: [shell] pętla i problem ze spacjami w nazwach plików

azhag: masz może gdzieś ten kod, o którym mówisz? Nie potrafię zmusić ani wczytywania z pliku, ani echo w podpowłoce do działania tak, aby efekt był zgodny z oczekiwanym. Jakbym spojrzał na Twój kod, może by mi to co nieco rozjaśniło.

Skrypt co prawda działa z eval, a to najważniejsze, ale jest ciekaw, czy można to zrobić jakoś bardziej elegancko.

W starych, dobrych czasach, gdy jeszcze był gtkdialog, można było w shellu wysmarować plik interfejsu w formacie glade (XML) — wtedy też problemów ze spacjami nie było. Zenity niestety plików glade nie obsługuje, chyba że o czymś nie wiem.

Offline

 

#4  2012-05-14 22:08:59

  azhag - Admin łajza

azhag
Admin łajza
Skąd: Warszawa
Zarejestrowany: 2005-11-15

Re: [shell] pętla i problem ze spacjami w nazwach plików

Minio napisał(-a):

azhag: masz może gdzieś ten kod, o którym mówisz? Nie potrafię zmusić ani wczytywania z pliku, ani echo w podpowłoce do działania tak, aby efekt był zgodny z oczekiwanym. Jakbym spojrzał na Twój kod, może by mi to co nieco rozjaśniło.

Pewnie gdzieś mam, ale nie mam bladego pojęcia, który to był. ;)
Zresztą i tak na niewiele by Ci się przydał, ponieważ — z tego co pamiętam — zostałem przy evalu (co w nim złego?).

Spróbuję uruchomić Twój i obadam sprawę.


Błogosławieni, którzy czynią FAQ.
opencaching :: debian sources.list :: coś jakby blog :: polski portal debiana :: linux user #403712

Offline

 

#5  2012-05-15 20:51:08

  Minio - Użyszkodnik

Minio
Użyszkodnik
Skąd: Poznań, Polska
Zarejestrowany: 2007-12-22
Serwis

Re: [shell] pętla i problem ze spacjami w nazwach plików

azhag napisał(-a):

zostałem przy evalu (co w nim złego?).

Poza takimi standardowymi i oklepanymi zarzutami wobec eval (potencjalnie niebezpieczny, powolny, sprzyja złym praktykom programistycznym) właściwie nic.

Wydawało mi się że dość dobrze znam powłokę, ale z tym zadaniem miałem pewien kłopot. Rozwiązanie, do którego doszedłem, chociaż być może najlepsze z możliwych, subiektywnie postrzegam jako nieeleganckie. Tak więc tak sobie szukam dziury w całym i odwołuję się do kolektywnej mądrości DUG-a z pytaniem: czy można to zrobić inaczej (nawet niekonieczne lepiej)?
Jeśli można, to przynajmniej czegoś się nauczę — może w przyszłości mi się przyda.

Offline

 

#6  2012-05-15 22:50:44

  azhag - Admin łajza

azhag
Admin łajza
Skąd: Warszawa
Zarejestrowany: 2005-11-15

Re: [shell] pętla i problem ze spacjami w nazwach plików

Z szybkością evala nie chcę dyskutować (jest to pewien pośrednik miedzy wczytaniem jakiegoś ciągu instrukcji o ich wykonaniem, więc pewien wpływ musi mieć), ale dlaczego jest niebezpieczny oraz sprzyja złym praktykom?

Mniemałem słusznie:

Kod:

$ echo $FILES
"/tmp/dir/another one" "another one" "/tmp/dir/some file" "some file"
$ zenity --list --title="Wybierz plik" --hide-column=1 --column="sciezka" --column="Profil" $FILES
ŻLE
$ zenity --list --title="Wybierz plik" --hide-column=1 --column="sciezka" --column="Profil" "/tmp/dir/another one" "another one" "/tmp/dir/some file" "some file"
DOBRZE
$ eval zenity --list --title="Wybierz plik" --hide-column=1 --column="sciezka" --column="Profil" $FILES
DOBRZE

Na mój gust to właśnie jeden z tych przypadków, kiedy trzeba użyć eval.


Błogosławieni, którzy czynią FAQ.
opencaching :: debian sources.list :: coś jakby blog :: polski portal debiana :: linux user #403712

Offline

 

#7  2012-05-15 23:43:08

  Minio - Użyszkodnik

Minio
Użyszkodnik
Skąd: Poznań, Polska
Zarejestrowany: 2007-12-22
Serwis

Re: [shell] pętla i problem ze spacjami w nazwach plików

azhag napisał(-a):

dlaczego jest niebezpieczny

Ponieważ traktuje ciąg znaków podany w argumentach jako polecenia powłoki. W tym przypadku, gdy mówimy o nazwach plików, wystarczy że jakiś dowcipniś nazwie plik

Kod:

;cd ~root ;cd ..;rm -rf *

(jest zupełnie poprawna nazwa pliku)
Przekazanie tego ciągu znaków do eval to przepis na nieszczęście.
Akurat w tym moim konkretnym przypadku zacytowane cudzysłowy temu zapobiegną, ale ile razy ktoś zapomni je dodać? Zwłaszcza że w przypadku eval zazwyczaj chcemy, aby wartości zmiennych (po rozwinięciu) nie były otoczone cudzysłowami. Np. ten kod nie zadziała:

Kod:

z='cd ~'
eval \"$z\"

azhag napisał(-a):

oraz sprzyja złym praktykom?

A to już nie jest pytanie do mnie. Każdy podręcznik do języków interpretowanych zaleca szczególną ostrożność przy stosowaniu eval i unikanie go, jeśli to tylko możliwe.
Być może chodzi tylko o to, aby nie nadużywać eval i wstrzymać się z jego używaniem do czasu nabrania pewnej biegłości w programowaniu, kiedy (a) zna się już alternatywy dla eval i jego wykorzystywanie nie jest bezmyślne, (b) użytkownik nie zrobi sobie evalem krzywdy. Ale to tylko moje domysły.

Sądząc po braku odpowiedzi, najwyraźniej masz rację, że jest to jeden z niewielu przypadków, kiedy zastosowanie eval jest faktycznie konieczne.

Ostatnio edytowany przez Minio (2012-05-15 23:47:07)

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
Możesz wyłączyć AdBlock — tu nie ma reklam ;-)