История изменений
Исправление
kalterfive,
(текущая версия)
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения — об этом и говорит сообщение об ошибке в ПП.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
(здесь всё нормально);a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);
Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас. А для массива мы сможем точно задать команду и каждый аргумент в частности.
Исправление
kalterfive,
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения — об этом и говорит сообщение об ошибке в ПП.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что для массива мы сможем точно задать команду и каждый аргумент в частности. И потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
(здесь всё нормально);a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);
Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас.
Исправление
kalterfive,
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения — об этом и говорит сообщение об ошибке в ПП.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
(здесь всё нормально);a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);
Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас.
Исправление
kalterfive,
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения — об этом и говорит сообщение об ошибке в ПП.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
(здесь всё нормально);a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);- Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас.
Исправление
kalterfive,
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения — об этом и говорит сообщение об ошибке в ПП.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
;a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);- Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас.
Исходная версия
kalterfive,
:
Твой код фиксится до рабочего так:
$ a="watch \"\$(df -h |grep ^[/F];free -h|sed 's/ \*/ /g')|sed 8q\""
$ $a
Это конструкция $( ... )
(man 1 bash | grep 'Command Substitution'
). Если использовать её, то на место первого аргумента bash подставит результат выполнения некоторой команды в этой конструкции. Если же её не использовать, то watch
получит первым аргументом саму команду, а не результат её выполнения.
Note: тем не менее, я не понимаю почему корректно работают конструкции с пайпом и eval-ом =)
Но суть проблемы я понял. Решение — испоьзовать массив вместо строки. Потому что bash может смотреть на исполняемое значение в строке так и только так:
"$a"
— это одна команда, вне зависимости от предполагаемого количества аргументов, экранируемых символов, и т. д.ls /dev
(например) — одна команда;ls
— не команда, а/dev
— не аргумент, ноls /dev
— одна команда.$a
— bash всё-таки попытается отделить команду от аргументов и правильно их выполнить, но может ошибиться из-за пробелов:a='ls arch' && $a
==ls arch
;a='ls "arch linux"'
==ls \"arch linux\"
(т. е. ls для директорий"arch
иlinux"
, но не для"arch linux"
);- Хинт: суть в том, что мы не можем достаточно (достаточно для корректности) точно задать команду в строке; во втором примере мы не можем указать начало и конец первого аргумента, bash это делает за нас.