Re: почему глючит ls
On 2016-01-23, dimas wrote:
> да уж, прикол... а кто-нибудь может объяснить, почему в случае с touch "-l"
> аргумент в кавычках все равно парсится как ключ?
Откройте POSIX:
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
2. Shell Command Language
The shell operates according to the following general overview of
operations. The specific details are included in the cited sections of this
chapter.
The shell reads its input from a file (see sh), from the -c option or
from the system() and popen() functions defined in the System Interfaces
volume of IEEE Std 1003.1-2001. If the first line of a file of shell
commands starts with the characters "#!", the results are unspecified.
The shell breaks the input into tokens: words and operators; see Token
Recognition.
The shell parses the input into simple commands (see Simple Commands)
and compound commands (see Compound Commands).
The shell performs various expansions (separately) on different parts of
each command, resulting in a list of pathnames and fields to be treated
as a command and arguments; see Word Expansions.
The shell performs redirection (see Redirection) and removes redirection
operators and their operands from the parameter list.
The shell executes a function (see Function Definition Command),
built-in (see Special Built-In Utilities), executable file, or script,
giving the names of the arguments as positional parameters numbered 1 to
n, and the name of the command (or in the case of a function within a
script, the name of the script) as the positional parameter numbered 0
(see Command Search and Execution).
The shell optionally waits for the command to complete and collects the
exit status (see Exit Status for Commands).
Т.е. при разборе строки происходит несколько шагов. С ``touch "-l"`` мы на шаге:
The shell breaks the input into tokens: words and operators; see Token
Recognition.
Смотрим по ссылке:
2.3 Token Recognition
If the current character is backslash, single-quote, or double-quote (
'\', '", or ' )' and it is not quoted, it shall affect quoting for
subsequent characters up to the end of the quoted text. The rules for
quoting are as described in Quoting. During token recognition no
substitutions shall be actually performed, and the result token shall
contain exactly the characters that appear in the input (except for
<newline> joining), unmodified, including any embedded or enclosing quotes
or substitution operators, between the quote mark and the end of the
quoted text. The token shall not be delimited by the end of the quoted
field.
If the current character is an unquoted <blank>, any token containing the
previous character is delimited and the current character shall be
discarded.
If the previous character was part of a word, the current character shall
be appended to that word.
Вот и обьяснение. Кавычки попадают в shell, обрабатываются и не доходят до
команды. Т.е. кавычки - это особенность shell, команда вообще ни при чем.
В разных контекстах выполняются разные шаги. Стоит раз разобраться.
Например ``Parameter Expansion`` не делается в одинарных кавычках.
Для проверки на пустоту важно взять параметер в двойные кавычки. built-in Bash
test как то отрабатывает:
$ [ -z -a -z ]
$ x=
$ [ -z $x -a -z $x ]
В GNU coreutils это не срабатывает:
bash# /usr/bin/\[ -z -a -z ]
/usr/bin/[: extra argument ‘-z’
bash# /usr/bin/\[ -z $x -a -z $x ]
/usr/bin/[: extra argument ‘-z’
В FreeBSD sh также не позволяет:
$ [ -z -a -z ]
[: -a: unexpected operator
$ [ -z $x -a -z $x ]
[: -a: unexpected operator
Расширение Bash работает двояко:
$ [[ -z ]]
bash: unexpected argument `]]' to conditional unary operator
bash: syntax error near `]]'
тогда как это сработает:
bash# [[ -z $x ]]
Признаюсь что у меня нет 100% гарантии с обьяснения мануала почему оно
работает. Прямо так не сказано. bash(1):
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed of the
primaries described below under CONDITIONAL EXPRESSIONS. Word
splitting and pathname expansion are not performed on the words
between the [[ and ]]; tilde expansion, parameter and variable
expansion, arithmetic expansion, command substitution, process
substitution, and quote removal are performed. Conditional operators
such as -f must be unquoted to be recog‐ nized as primaries.
See the description of the test builtin command (section SHELL BUILTIN
COMMANDS below) for the handling of parameters (i.e. missing
parameters).
Т.е. сделается пустая подстановка вместо $x, но место быдет считаться занятым
потому что не происходит Word splitting?
Переносимый синтаксис:
$ [ -z "$x" -a -z "$x" ]
Еще пример Bash расширения когда от контекста зависит какие шаги выбираются по
преобразованию строки:
$ [[ axa == *x* ]] && echo ok
Вспоминаем что в ``[[`` не делается pathname expansion и дополнительно:
When the == and != operators are used, the string to the right of the operator
is considered a pattern and matched according to the rules described below
under Pattern Matching, as if the extglob shell option were enabled.
Этим пользуюсь вместо:
case axa in *x*) echo ok;; esac
--
http://defun.work/
Reply to: