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/