qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
qkowlew ([personal profile] qkowlew) wrote2017-02-01 03:03 am

Админам, пишущим на bash..

Прикол для очень внимательных и опытных писателей на bash.

Однажды отец Онуфрий опытный админ написал кусок кода, обходящий окрестности онежского дерево каталогов, и стал его применять везде где ни попадя:
SqTree(){
[ -z "${1}" ] && return
for i in *.html
 do
 [ -s "${i}" ] && (тут обработка строк файла, не важно какая)
 done
for i in *
 do
 [ -d "${i}" ] || continue
 cd "${i}"
 SqTree "${1}"
 cd ..
 done
}

Скажите, собратия по написанию скриптов на bash и многих других шеллах - чего не хватает конкретно в выделенной полужирным строке, и почему? :)

UPD 2017-02-01 15:53 : пока из 6 участвующих в о[б|]суждении обнаружил "самую интересную" ошибку только один (в ирц, не здесь). :)

UPD 2017-02-01 19:05 : чтобы избавить данный вопрос от претензии "почему не find" - та же самая "недостача" в такой же выделенной строке скрипта вида:
#!/bin/bash
# Show subdirectory listing
[ -z "$1" ] && return
[ -d "$1" ] || return
cd "$1"
ls
cd ..
vitus_wagner: My photo 2005 (Default)

[personal profile] vitus_wagner 2017-02-01 06:44 am (UTC)(link)
set -e
в начале скрипта помогает. А вообще код завершения команды cd не проверять бывает очень больно.
vitus_wagner: My photo 2005 (Default)

[personal profile] vitus_wagner 2017-02-01 02:00 pm (UTC)(link)
Неужели именно в самой? А не в вышележащей команде for?

Можно же написать for i in ./*; do
filin: (Default)

[personal profile] filin 2017-02-01 02:02 pm (UTC)(link)
Витус, можно, но так точно никто не пишет :)
vitus_wagner: My photo 2005 (Default)

[personal profile] vitus_wagner 2017-02-01 02:05 pm (UTC)(link)
Ну я по крайней мере так пишу в аргументе find. Привык уже, что пустой файлик с именем -rf где-то да существует, поэтому все пути в текущем поддереве должны начинаться с ./
vitus_wagner: My photo 2005 (Default)

[personal profile] vitus_wagner 2017-02-01 05:26 pm (UTC)(link)
Тогда претензия "почему не прочитать man ls и не сделать это одной командой ls "$1""?

Ну и вообще, кто пишет скрипты на баше, тот сам себе буратина. Если тебе не хватает стандартного sh, то надо уже нормальный скриптовывй язык брать. Ты ж вроде BSD-шник. Откуда у тебя bash в /bin?
vitus_wagner: My photo 2005 (Default)

[personal profile] vitus_wagner 2017-02-01 07:35 pm (UTC)(link)
Ку, на табличке твоим же собственным голосом написано "Ты невнимателен"
Я тебе еще сколько комментариев назад предложил заменить * в for на ./*
Это решает все проблемы с именами файлов, начинающимися с минусов. И решает их на этапе генерации списка имен, а не на этапе его использования.

Человек, имеющий дело с FreeBSD, по крайней мере знает, что на свете бывает настоящий sh, который не баш.
В отличие от человека, который никаких POSIX-систем кроме GNU не видал, а GNU, как известно is not Unix.
FreeBSD в общем-то тоже is not Unix, поскольку там весть закопирайченный код AT&T давным-давно переписали,
но она хотя бы похожа. Более того, если мне не изменяет память, ты же сам с месяц назад в какой-то дискуссии утверждал что не надо полагаться на наличие в системе bash, а то вдруг /usr/local не смонтировался корректно, и надо залогиниться, чтобы это исправить.

Но вообще я специально держал виртуалку с solaris, чтобы тестировать кое-какие вещи в настоящем Unix, который на базе system V-вской codebase. Сейчас у меня все равно настоящий спарк под рукой есть, поскольку тестировать сишный код на big-endian со strict-alignment тоже крайне полезно.

Мое мнение (кстати, практически выстраданное, и много кем разделяемое) - шелловские скрипты надо писать на /bin/sh.
И его же в шебанг прописывать. И как только тебе неудержимо захотелось упоребить в скрипте башизм, это повод переписать его c shell на perl или python. bash - только для интерактивной работы. По поводу zsh у тех, кто его активно используют может быть другое мнение. Там вроде немножко поаккуратнее это сделано.

dmarck: (Default)

[personal profile] dmarck 2017-02-04 09:12 am (UTC)(link)
for не может не оказаться, for -- это shell builtin!
dmarck: (Default)

[personal profile] dmarck 2017-02-05 10:03 am (UTC)(link)
не-не. for является непременно реализованной функцией любого korn-style POSIX шелла.

А chdir (cd) -- единственная функция, которая не может быть реализованной как внешний бинарник -- потому что внешний бинарник не может поменять working directory вызывающему. ;-P
filin: (Default)

[personal profile] filin 2017-02-01 02:02 pm (UTC)(link)
Ты имел в виду ./?

Так сразу и говори: "в этом коде проблемы через строку, но я хочу, чтобы вы угадали некоторую конкретную именно в этой строке. Да, я знаю, что и в ней их тоже больше одной."

Или ты не знаешь, что в этой строке больше одной проблемы типа "не хватает"?
filin: (Default)

[personal profile] filin 2017-02-01 08:34 pm (UTC)(link)
Четвертая проблема мне пока в голову не приходит. Но я еще попробую на свежую голову...