Неожиданное поведение с эхом [[:digit:]]

Inicie sesión sin contraseña en MySQL a través de

mysql -uroot

Luego cambie la contraseña de root a través de

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('myp4ssw0rd');
FLUSH PRIVILEGES;
10
08.03.2018, 22:55
3 ответа

{1,2,3}(y e. gramo. {1..3}son ​​expansiones de tornapuntas . Son interpretados por el shell antes de la ejecución del comando.

[[:digit:]]es un token que coincide con el patrón , pero no lo está utilizando en una ubicación con ningún archivo que coincida con ese patrón. Si usa una coincidencia de patrón que no tiene coincidencias, se expande a sí misma:

$ echo [[:digit:]]; touch 3; echo [[:digit:]]
[[:digit:]]
3
4
27.01.2020, 19:59

Потому что это две разные вещи. {1,2,3}является примером раскрытия фигурной скобки . Конструкция {1,2,3}расширяется оболочкой еще до того, как echoее увидит. Вы можете увидеть, что произойдет, если вы используетеset -x:

$ set -x
$ echo {1,2,3}
+ echo 1 2 3
1 2 3

Как видите, команда echo {1,2,3}расширена до:

echo 1 2 3

Однако [[:digit:]]является классом символов POSIX . Когда вы передаете его echo, оболочка также сначала обрабатывает его, но на этот раз он обрабатывается как глобус оболочки . это работает так же, как если бы вы запустили echo *, который напечатает все файлы в текущем каталоге. Но [[:digit:]]— это глобус-оболочка, который будет соответствовать любой цифре. Теперь в bash, если глобус оболочки ничему не соответствует, он будет расширен до самого себя :

.
$ echo /this*matches*no*files
+ echo '/this*matches*no*files'
/this*matches*no*files

Если глобус действительно соответствует чему-то, это будет напечатано:

$ echo /e*c
+ echo /etc
/etc

В обоих случаях echoпросто печатает то, что говорит оболочка, но во втором случае, поскольку glob соответствует чему-то (/etc), ему предлагается напечатать это что-то.

Таким образом, поскольку у вас нет файлов или каталогов, имя которых состоит ровно из одной цифры (, а это то, что [[:digit:]]соответствует ), глобус расширяется до самого себя, и вы получаете:

$ echo [[:digit:]]
[[:digit:]]

Теперь попробуйте создать файл с именем 5и запустить ту же команду:

$ echo [[:digit:]]
5

И если есть более одного совпадающего файла:

$ touch 1 5       
$ echo [[:digit:]]
1 5

Это (своего рода ), описанное в man bashв объяснении параметров nullglob, которые отключают это поведение:

nullglob
    If  set,  bash allows patterns which match no files (see
    Pathname Expansion above) to expand to  a  null  string,
    rather than themselves.

Если вы установите этот параметр:

$ rm 1 5
$ shopt -s nullglob
$ echo [[:digit:]]  ## prints nothing

$ 
34
27.01.2020, 19:59

{1,2,3}— эторасширение фигурной скобки ,он распространяется на перечисленные слова независимо от их значения.

[...]— это группа символов, используемая врасширении имени файла(или подстановочном знаке или подстановочном знаке )аналогично звездочке *и вопросительному знаку ?. Он соответствует любому отдельному символу, указанному внутри, или символам, которые являются членами именованных групп, таких как [:digit:], если они перечислены. По умолчанию большинство оболочек оставляют подстановочный знак как -, если нет файлов, соответствующих ему.

(Обратите внимание, что вы не можете превратить подстановочный знак/шаблон в набор строк, которым он будет соответствовать. Звездочка может соответствовать любой строке любой длины, поэтому расширение любого шаблона, содержащего ее, приведет к бесконечному списку строк.)

Так:

$ bash -c 'echo [[:digit:]]'           # bash leaves it as-is
[[:digit:]]
$ zsh -c 'echo [[:digit:]]'            # zsh by default complains if no match
zsh:1: no matches found: [[:digit:]]
$ touch 1 3 d i g t
$ bash -c 'echo [[:digit:]]'           # now there are two matches
1 3                                    # note that d, i, g and t do NOT match

Но все же:

$ bash -c 'echo {1,2,3}'
1 2 3

Обе они расширяются оболочкой , не имеет значения, какую команду вы выполняете: ls, echoили rm. Также обратите внимание, что если любой из них указан в кавычках, они не будут расширены:

$ bash -c 'echo "[[:digit:]]"'         # even though matching files still exist
[[:digit:]]
$ bash -c 'echo "{1,2,3}"'
{1,2,3}
14
27.01.2020, 19:59

Теги

Похожие вопросы