Odpowiedzi:
for d in ./*/ ; do (cd "$d" && somecommand); done
for d in ./*/uruchamia pętlę, w której zapisywany jest każdy element ./*/(w tym przypadku lista plików / folderów) w zmiennej $d. do (cd "$d" && somecommand);uruchamia ciało pętli. Wewnątrz ciała uruchamia podpowłokę i uruchamia polecenia cdi somecommand. Ponieważ jest to powłoka podrzędna, powłoka nadrzędna (powłoka, z której uruchamiane jest to polecenie), zachowuje CWD i inne zmienne środowiskowe. donepo prostu zamyka korpus pętli.
for d in ./*/ ; do (cd "$d" && ls); donenie będzie działać. ale for d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); donezadziała. -korzystanie z ls jako polecenia w tym przykładzie.
-bash: cd: ./*/: No such file or directory
Najlepszym sposobem jest w ogóle nie używać cd:
find some/dir -type f -execdir somecommand {} \;
execdirjest jak exec, ale katalog roboczy jest inny:
-execdir command {} [;|+]
Like -exec, but the specified command is run from the
subdirectory containing the matched file, which is not normally
the directory in which you started find. This a much more
secure method for invoking commands, as it avoids race
conditions during resolution of the paths to the matched files.
To nie jest POSIX.
findwykonuje te polecenia, więc nie byłby świadomy aliasów. Co to mdjest .linkkatalog?
bash: find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;Nie trzeba robić catz wget, który ma -iflagę do czytania w URL z pliku. Również nieco różni się to od twojego pierwotnego pytania (ponieważ wydaje się, że jesteś zainteresowany tylko nazwanymi plikami, .linka nie innymi, które mogą być obecne).
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
printf %s\\n "$PWD" >&2
command && cd "$OLDPWD" ||
! break; done || ! cd - >&2
Powyższe polecenie nie musi wykonywać żadnych podpowłok - po prostu śledzi swoje postępy w bieżącej powłoce na przemian $OLDPWDi $PWD. Kiedy ty cd -powłoka wymienia wartość tych dwóch zmiennych, w zasadzie, ponieważ zmienia katalogi. Wyświetla także nazwę każdego katalogu, ponieważ działa tam na stderr.
Właśnie rzuciłem na to okiem i zdecydowałem, że lepiej sobie radzę z obsługą błędów. Pominie katalog, do którego nie może cd- i cdwydrukuje komunikat o tym, dlaczego stderr - i breakw / niezerowy kod wyjścia, jeśli commandnie zostanie wykonany pomyślnie lub jeśli uruchomienie w commandjakiś sposób wpłynie na jego zdolność do powrotu do oryginalnego katalogu - $OLDPWD. W takim przypadku wykonuje również cd -ostatni - i zapisuje wynikową bieżącą nazwę katalogu roboczego do stderr.
youtube-dl.