Кавычки в if

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

lazhu
Сообщения: 70
ОС: FreeBSD 9-STABLE / clang 3.3

Кавычки в if

Сообщение lazhu » 31.10.2014 20:01

Вопрос на засыпку.
Есть вот такой скриптик:

Код: Выделить всё

#!/bin/sh

SRC="/var/spool/altqueue"
DST="$SRC/ready"
cmd="sendmail -OQueueDirectory=$DST -C /etc/mail/sendmail_t.cf -q"
q="q*"

if [ -f "$DST/$q" ]; then
    $cmd; exit
elif [ ! -f "$SRC/$q" ]; then
    exit
fi

cd $SRC

c=0
for i in $q; do
    if [ $c -eq 5 ]; then
        break
    fi
    f=`echo $i | tail -c+2`
    mv $i d$f $DST
    c=`expr $c + 1`
done

sleep 1
$cmd

Долгое время он вполне себе нормально отрабатывал, но в какой-то момент вдруг перестал копировать файлы из $SRC в $DST, несмотря на их наличие в первой.
Вылечилось убиранием кавычек отсюда:

Код: Выделить всё

if [ -f $DST/$q ]; then
    $cmd; exit
elif [ ! -f $SRC/$q ]; then
    exit
fi


Система:

Код: Выделить всё

uname -a
FreeBSD router.apnet.local 8.3-RELEASE FreeBSD 8.3-RELEASE #0: Fri Jan  4 17:11:04 MSK 2013     root@router.apdom.local:/usr/obj/usr/src/sys/FIREWALL  amd64

Система не обновлялась, /bin/sh остался прежним:

Код: Выделить всё

ls -l /bin/sh
-r-xr-xr-x  1 root  wheel  137504 Apr 10  2012 /bin/sh

Может кто-то объяснить уличную магию?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 31.10.2014 22:56

lazhu писал(а):
31.10.2014 20:01
q="q*"

А как это должно было работать?
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

lazhu
Сообщения: 70
ОС: FreeBSD 9-STABLE / clang 3.3

Re: Кавычки в if

Сообщение lazhu » 01.11.2014 14:08

Bizdelnick писал(а):
31.10.2014 22:56
lazhu писал(а):
31.10.2014 20:01
q="q*"

А как это должно было работать?


Мда, что-то я упустил тот факт, что test принимает только один аргумент. Сделал костыль из ls | wc, благо кроме сообщений там ничего быть не может, достаточно проверить, что каталог пустой/не пустой.
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 02.11.2014 20:49

lazhu писал(а):
31.10.2014 20:01
f=`echo $i | tail -c+2`

facepalm

Код: Выделить всё

f="${i:1}"

lazhu писал(а):
01.11.2014 14:08
достаточно проверить, что каталог пустой/не пустой

double facepalm
man test, опция -s зачем??
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 02.11.2014 20:54

drBatty писал(а):
02.11.2014 20:49

Код: Выделить всё

f="${i:1}"

Это башизм.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 02.11.2014 20:56

lazhu писал(а):
31.10.2014 20:01
cmd="sendmail -OQueueDirectory=$DST -C /etc/mail/sendmail_t.cf -q"

oh shi~

А почему не функция?? Зачем это извращение?
lazhu писал(а):
31.10.2014 20:01
c=`expr $c + 1`

напоследок:

Код: Выделить всё

(( c++ ))
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 02.11.2014 20:57

drBatty писал(а):
02.11.2014 20:56

Код: Выделить всё

(( c++ ))

И это тоже...
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 02.11.2014 21:01

Bizdelnick писал(а):
02.11.2014 20:54
Это башизм.

а вы уверены, что конструкция `tail -c+2` _везде_ будет работать?

Bizdelnick писал(а):
02.11.2014 20:57
И это тоже...

тоже вопрос: является-ли конструкция

Код: Выделить всё

c=`expr $c + 1`

более переносимой? Она такая ПЕРЕНОСИМАЯ, что можно наплевать на её нечитаемость и сложность??
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 02.11.2014 21:09

drBatty писал(а):
02.11.2014 21:01
Bizdelnick писал(а):
02.11.2014 20:54
Это башизм.

а вы уверены, что конструкция `tail -c+2` _везде_ будет работать?

Гарантию, как известно, могут дать только облигации государственного займа, но по крайней мере она должна работать по стандарту.

drBatty писал(а):
02.11.2014 21:01
Bizdelnick писал(а):
02.11.2014 20:57
И это тоже...

тоже вопрос: является-ли конструкция

Код: Выделить всё

c=`expr $c + 1`

более переносимой? Она такая ПЕРЕНОСИМАЯ, что можно наплевать на её нечитаемость и сложность??

Да.
Хотя есть более простой и немного более читаемый переносимый вариант:

Код: Выделить всё

c=$(($c + 1))


P. S. Насколько я понимаю, ТСу надо, чтобы скрипт работал в одном отдельно взятом шелле, причём с высокой долей вероятности это не bash.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 02.11.2014 22:21

Bizdelnick
ладно, убедили.
А что там по дефолту во фряхе вместо шелла?

PS: 2ТС: вы бы хоть предупреждали, какой у вас шелл? И почему вы его не замените на удобный и простой bash?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

lazhu
Сообщения: 70
ОС: FreeBSD 9-STABLE / clang 3.3

Re: Кавычки в if

Сообщение lazhu » 03.11.2014 10:52

drBatty писал(а):
02.11.2014 22:21
Bizdelnick
ладно, убедили.
А что там по дефолту во фряхе вместо шелла?

PS: 2ТС: вы бы хоть предупреждали, какой у вас шелл? И почему вы его не замените на удобный и простой bash?

Спасибо, у меня простой и удобный zsh. Как вам уже сказали выше, мой скрипт будет работать в любой системе. Даже в ваших линуксах bourn shell еще не убили.
Спасибо сказали:

lazhu
Сообщения: 70
ОС: FreeBSD 9-STABLE / clang 3.3

Re: Кавычки в if

Сообщение lazhu » 03.11.2014 11:13

drBatty писал(а):
02.11.2014 20:49
lazhu писал(а):
31.10.2014 20:01
f=`echo $i | tail -c+2`

facepalm

Код: Выделить всё

f="${i:1}"


facepalm
В первой строчке скрипта английским по-белому написано, какой шелл.
drBatty писал(а):
02.11.2014 20:49
lazhu писал(а):
01.11.2014 14:08
достаточно проверить, что каталог пустой/не пустой

double facepalm
man test, опция -s зачем??

Код: Выделить всё

~ % man test | grep '\-s'
     -s file   True if file exists and has a size greater than zero.

Вы про это? И что дальше?
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 03.11.2014 11:54

lazhu писал(а):
03.11.2014 10:52
Спасибо, у меня простой и удобный zsh.

так бы сразу и сказали.
lazhu писал(а):
03.11.2014 11:13
В первой строчке скрипта английским по-белому написано, какой шелл.

Shell

$ /bin/sh --version GNU bash, version 4.3.27(1)-release (i486-slackware-linux-gnu)


lazhu писал(а):
03.11.2014 11:13
-s file True if file exists and has a size greater than zero.

Вы про это? И что дальше?

а вот тут я что-то ошибся. Спутал с

Код: Выделить всё

FIND(1)                                General Commands Manual                                FIND(1)

       -empty File is empty and is either a regular file or a directory.

я думал, что test тоже пустые каталоги умеет:

Код: Выделить всё

      -s FILE        True if file exists and is not empty.
Оказалось: увы, не умеет. Что для bash::test, что для /bin/test пустой каталог не пуст почему-то…
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Kopilov
Сообщения: 670
ОС: Gentoo, Debian

Re: Кавычки в if

Сообщение Kopilov » 03.11.2014 12:26

drBatty писал(а):
03.11.2014 11:54
пустой каталог не пуст почему-то…

Вероятно, потому, что

Код: Выделить всё

mkdir empty
ls -a empty
.  ..
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 03.11.2014 12:49

lazhu писал(а):
03.11.2014 11:13
В первой строчке скрипта английским по-белому написано, какой шелл.

/bin/sh в разных системах разный. В последних версиях Debian, например, по умолчанию это dash, а раньше был bash. Я привык считать, что это априори неведомый, но POSIX-совместимый шелл.

Kopilov писал(а):
03.11.2014 12:26
Вероятно, потому, что

Код: Выделить всё

mkdir empty
ls -a empty
.  ..

Точнее, потому что

Shell

% mkdir empty % ls -ldh empty drwxr-xr-x 2 user user 4,0K Ноя 3 12:48 empty %

Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 2669
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Кавычки в if

Сообщение Hephaestus » 05.11.2014 15:38

Bizdelnick писал(а):
03.11.2014 12:49
/bin/sh в разных системах разный. В последних версиях Debian, например, по умолчанию это dash, а раньше был bash.
Я правильно понимаю, что раньше
#!/bin/sh и #!/bin/bash означали одно и то же?
А то помнится, у меня некоторые конструкции в скриптах (типа арифметических операций с переменными) правильно работали только при явном указании bash.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 05.11.2014 15:45

Hephaestus

Shell

% readlink /bin/sh dash %

Раньше вроде бы был bash, но уже не помню, начиная с какой версии его заменили. И не только в Debian, кстати.

Hephaestus писал(а):
05.11.2014 15:38
некоторые конструкции в скриптах (типа арифметических операций с переменными) правильно работали только при явном указании bash.

Я выше указывал переносимый вариант арифметической подстановки. Ну или expr использовать, как ТС.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

lazhu
Сообщения: 70
ОС: FreeBSD 9-STABLE / clang 3.3

Re: Кавычки в if

Сообщение lazhu » 06.11.2014 09:17

Bizdelnick писал(а):
05.11.2014 15:45
Hephaestus

Shell

% readlink /bin/sh dash %

Раньше вроде бы был bash, но уже не помню, начиная с какой версии его заменили. И не только в Debian, кстати.

Hephaestus писал(а):
05.11.2014 15:38
некоторые конструкции в скриптах (типа арифметических операций с переменными) правильно работали только при явном указании bash.

Я выше указывал переносимый вариант арифметической подстановки. Ну или expr использовать, как ТС.

Арифметика работает, но expr приходит на ум быстрее =)
В BSD /bin/sh - это /bin/sh. Bourn shell, то есть.

Код: Выделить всё

 ~  man sh
...
HISTORY
     A sh command, the Thompson shell, appeared in Version 1 AT&T UNIX.  It
     was superseded in Version 7 AT&T UNIX by the Bourne shell, which inher‐
     ited the name sh.

     This version of sh was rewritten in 1989 under the BSD license after the
     Bourne shell from AT&T System V Release 4 UNIX.
...
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 2669
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Кавычки в if

Сообщение Hephaestus » 06.11.2014 10:28

Bizdelnick писал(а):
05.11.2014 15:45
Я выше указывал переносимый вариант арифметической подстановки.
Я к тому, что если /bin/sh и /bin/bash - это было одно и то же, то я не заметил бы разницы. А разница была.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 12.11.2014 08:20

Kopilov писал(а):
03.11.2014 12:26
Вероятно, потому

не. Это особые ссылки. Они к этому каталогу не относятся, их не нужно считать.
Bizdelnick писал(а):
03.11.2014 12:49
drwxr-xr-x 2 user user 4,0K Ноя 3 12:48 empty

ну и что?

$

drb@amilo:/tmp$ mkdir empty drb@amilo:/tmp$ find -empty -ls 4196497 0 drwxr-xr-x 2 drb users 40 ноя 12 08:04 ./empty


(а вот find -size 0 не находит)
Hephaestus писал(а):
05.11.2014 15:38
Я правильно понимаю, что раньше
#!/bin/sh и #!/bin/bash означали одно и то же?

когда bash не было — да. Есть и сейчас такой shell в слаке (man 1 sh)

Код: Выделить всё

DESCRIPTION
     Sh is the standard command interpreter for the system. The current version of sh is in the
     process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the
     shell.  This version has many features which make it appear similar in some respects to the Korn
     shell, but it is not a Korn shell clone (see ksh(1)).  Only features designated by POSIX, plus a
     few Berkeley extensions, are being incorporated into this shell.  We expect POSIX conformance by
     the time 4.4 BSD is released. This man page is not intended to be a tutorial or a complete spec‐
     ification of the shell.


Если bash запущен как sh, то он подделывается под sh, т.е. некоторые конструкции работают как в sh(1), а не как в bash. Это те, которые и там и там _могут_ работать. Но башизмы, которые вызовут ошибку в sh(1), в bash работают нормально, даже если он вызван как /bin/sh.

PS: система считает /bin/sh оболочкой по умолчанию. Т.е. если в скрипте вообще не указать

Код: Выделить всё

#!/bin/bash

а просто писать код, то система вызовет /bin/sh. В Linux это какой-то shell, обычно bash. Но сейчас мода пошла избавляться от bash, ибо он "медленный" и "fork много памяти ест". Ну компьютеры видно не справляются. 20 лет назад компьютеры справлялись как-то с bash'ем…
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 12.11.2014 08:51

lazhu писал(а):
06.11.2014 09:17
но expr приходит на ум быстрее

субъективно.

expr(1) это недоделанный примитивный калькулятор. Если уж калькулятор, то bc(1)

Ну а посчитать 2*2 сама оболочка должна уметь ИМХО, без костылей.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 12.11.2014 10:24

drBatty писал(а):
12.11.2014 08:51
Ну а посчитать 2*2 сама оболочка должна уметь ИМХО, без костылей.

Так она и умеет.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Кавычки в if

Сообщение drBatty » 14.11.2014 03:19

Bizdelnick писал(а):
12.11.2014 10:24
Так она и умеет.

как?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 16115
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Кавычки в if

Сообщение Bizdelnick » 14.11.2014 10:11

drBatty писал(а):
14.11.2014 03:19
как?

Так, как я писал выше:

Код: Выделить всё

a=$((2*2))
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали: