[freebsd] test и пустые строки

Irina Liakh spell at itl.ua
Tue Nov 21 14:55:11 EET 2017


On Tue, Nov 21, 2017 at 11:55:06AM +0200, Valentin Nechayev wrote:
> 
>  Tue, Nov 21, 2017 at 11:40:47, spell wrote about "Re: [freebsd] test и пустые строки": 
> 
> > Согласна, но почему бы об этом не упомянуть в мане? Сэкономило бы много
> > времени не только мне. А лучше переписать usage syntax.
> > Вот эта строка:
> > 
> >      string        True if string is not the null string.
> > 
> > и работающая конструкция "[ ]" дают надежду на то, что аргументы могут
> > быть null'ами (это если не задумываться о реализации и наследии).
> > Поскольку в околошелльных кругах нет устоявшихся понятий
> > "null string", "zero string", "initialized variable" (нет же?), то
> > описание типа такого, кмк, было бы более прозрачным:
> > 
> >      [string]      True if string is specified and it's length is not zero.
> 
> Да, тут понятие null string требует расшифровки или замены на более
> понятное, типа empty string.

Empty string не годится потому что в таком случае не отражает реальное
положение вещей. Синтаксис же допускает как non-zero-length string и
zero-lengh string так и отсутствие оной.

> > [ `somelongcommandline` ] && dosomething || doother
> > 
> > выглядит получше чем
> > 
> > [ -n "`somelongcommandline`" ] && dosomething || doother
> 
> Мнэээ... вообще-то это уже диверсия. Например:
> 
> $ a() { echo 1 -eq 3; }
> $ [ `a` ] && echo yes || echo no
> no
> $ a() { echo 1 -ne 3; }
> $ [ `a` ] && echo yes || echo no
> yes
> $ a() { echo 1 2 3; }
> $ [ `a` ] && echo yes || echo no
> bash: [: 2: binary operator expected
> no
> 
> то есть отсутствием закавычивания Вы уже пришли к тому, что
> `somecommand` может выдавать несколько разделённых пробелом слов,
> которые будут рассматриваться отдельно.
> Это крайне хрупко и может быстро привести к настоящим дырам в
> безопасности.
> Я в таких случаях _никогда_ не надеюсь на постулаты типа "эта команда
> никогда не выдаст более одного слова";

Даже если эта команда - "echo 1"? ;)
Моя команда точно не выводит более одного слова :)

> если где-то записано `x` вместо
> "`x`", это следует считать прямой командой шеллу перепарсить вывод, а
> такие команды не надо использовать, если нет на то прямого указания.

Не поняла, почему "перепарсить"?

> > > Как и вообще многое в шелле и вокруг. Test тут далеко не
> > > единственный пример. Возьмём grep. Мы можем десятки раз писать что-то
> > > типа "grep vasya /var/log/auth.log", но если шаблон приходит снаружи,
> > > мы обязаны написать:
> > > 
> > > grep -e "$pattern" "$file"
> > > 
> > > причём важны и -e - указать, что тут шаблон, и кавычки - чтобы шелл
> > > сохранил это одним аргументом, независимо от количества параметров в
> > > нём.
> > 
> > С grep всё очевидно и согласно процедурам word expansion и quote removal.
> 
> Это про кавычки, а я также про -e для шаблона, который может
> начинаться с '-'.

Разумеется.
Очевидно, потому что понятно, как ведёт себя grep после подстановки переменных,
и что без -e и без закавычивания паттерна он будет рассматривать аргументы
командной строки как и положено (но не так как нужно): строки с ведущими "-"
как опции, первый аргумент как паттерн, остальные как файлы.

> Ну и если "всё очевидно", то что мешает упростить работу шеллу в
> случае test?

В смысле?

> > Да-да..
> > Если бы мне дали всё исправить, я бы начала с того, что 0 - это true,
> > а 1 - false. (начиная с машинной логики, а не только в шеллах)
> 
> Вот тут не согласен. В шелле такая логика потому, что успешных
> завершений один код, а неуспешных - много. Но именно поэтому она
> обратная.

Имхо, в шелле как раз нормальная логика. Успех - он и в Африке успех,
для него достаточно одного кода. А поводов для файлура может быть
множество, и когда каждый код выхода означает определённый reason -
это просто счастье и благодать. И естественно отдать 0, как единственный
в своём роде, успеху, а остальные ненули - ошибкам.
И очень легко делать проверку: if (true), условно говоря.

А вот в Сишечке необходимость выворачивать наизнанку смысл
кода возврата:

    if (!somefunc()) printf("success")

меня расстраивает... Это при том, что логика кодов возврата
та же (0 - success, >0 - failure).

Да и вообще! 0 - true и 1 - false логично хотя бы потому, что
0 - это чёт, а 1 - нечет. Само по себе понятие "нечет" (а хоть бы даже и
odd) несёт в себе отрицательный смысл, и его логичней привязать к false.
Щетаю, что из "0 - false" растут многие сложности, созданные на ровном
месте и совершенно ненужные.

> И не везде она такая (вон в Windows положительные коды -
> успех, отрицательные - ошибка, и в обоих множествах 2 миллиарда
> возможностей).

Зашибись решение. Стоит только не проследить за типом данных
(signed/unsigned и длиной в байтах) как вуаля - лёгким движением руки
отрицательное превращается в положительное.



More information about the freebsd mailing list