qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
[personal profile] qkowlew
Прикол для очень внимательных и опытных писателей на 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 ..

Date: 2017-Feb-01, Wednesday 14:00 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Неужели именно в самой? А не в вышележащей команде for?

Можно же написать for i in ./*; do

Date: 2017-Feb-01, Wednesday 14:02 (UTC)
filin: (Default)
From: [personal profile] filin
Витус, можно, но так точно никто не пишет :)

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

Date: 2017-Feb-01, Wednesday 17:26 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Тогда претензия "почему не прочитать man ls и не сделать это одной командой ls "$1""?

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

Date: 2017-Feb-01, Wednesday 19:35 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Ку, на табличке твоим же собственным голосом написано "Ты невнимателен"
Я тебе еще сколько комментариев назад предложил заменить * в 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 у тех, кто его активно используют может быть другое мнение. Там вроде немножко поаккуратнее это сделано.

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

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

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