странное поведение дочерней оболочки, выполняющей команду с аргументами

#bash #subshell

#bash #дочерняя оболочка

Вопрос:

когда я выполняю следующую команду напрямую:

 root@busybox-694d76bb5d-2gcvh:/# mysql -hmariadb -P3306 -uroot -ppassword -e 'SELECT 1'
  

Я получаю следующий вывод:

 mysql: [Warning] Using a password on the command line interface can be insecure.
 --- 
| 1 |
 --- 
| 1 |
 --- 
  

Однако та же команда в дочерней оболочке, например, так:

 $(mysql -hmariadb -P3306 -uroot -ppassword -e 'SELECT 1')
  

выводит:

 mysql: [Warning] Using a password on the command line interface can be insecure.
bash: 1: command not found
  

почему bash интерпретирует «1», который я отправляю в качестве аргумента, как если бы это была отдельная команда, когда она отправляется в подоболочке?

Комментарии:

1. Какой bash вы используете? Я вижу некоторые busybox в вашей вставке…

2. У bash-4.2 меня нет такой ошибки в команде подоболочки.

3. ДА. Эта вставка из контейнера Docker, в котором запущен образ mysql из dockerhub. Однако я получаю такое же странное поведение на моем собственном терминале под управлением Ubuntu

4. Чтобы запустить команду на переднем плане в дочерней оболочке, используйте bash -c 'YOUR COMMAND GOES HERE' … хотя я не совсем понимаю, почему вы хотите это сделать. Чтобы сделать это в фоновом режиме, используйте YOUR COMMAND GOES HERE ! .

Ответ №1:

Bash интерпретирует не 1 эту часть аргументов, а выходные данные команды.

Во-первых, вам нужно знать, что mysql имеет два режима вывода по умолчанию: table и raw. Первый используется, когда поток вывода команды является терминалом и выводит удобочитаемый вывод. Вторая используется иначе и выводит результат, которым легко манипулировать скриптами. Вы можете принудительно выполнить одно или другое, используя параметры, документацию по которым я связал.

Во-вторых, вам нужно знать разницу между простым (subshell) и $(command substitution) : в обоих случаях команда выполняется в дочерней оболочке, но при подстановке команды вывод команды подставляется в исходную командную строку, которая затем выполняется.

Итак, что произошло, когда вы писали свой $(mysql command) , так это то, что его вывод был 1 (необработанный результат) вместо таблицы, которую вы ранее видели, которая затем не была проанализирована как команда.

Вы можете легче увидеть разницу между подоболочкой и подстановкой команд, протестировав разницу между (echo 1) и $(echo 1) , вторая из которых завершится ошибкой точно так же, как и ваша текущая команда.