Intereting Posts
Gnome – источник ввода не работает OpenVPN блокирует SMTP-сервер доступа полностью Предоставление PHP права на запись в файлы и папки Изменение разрешений папок в Debian Нет аналогового аудио с AMD E1 – HDMI "берет на себя" Как измерить использование сетевого трафика? Отключить завершение имени файла подстроки в zsh Как я запускаю сценарий n раз в одно и то же время и как имитировать семафор? Предотвращение блокировки доступа во время вращения внешнего жесткого диска? скрипт grep restart, если он не запущен aliasing cd to pushd – это хорошая идея? Как запустить скрипт на удаленном хосте, когда я потеряю соединение с ним? Синхронизация пакетов / конфигов / установка между компьютерами Стандартный / канонический способ проверить, выводит ли предыдущий трубопровод выпуск? Как включить перенаправление портов, но только для некоторых IP-адресов и блокировки других?

Можно ли скопировать расширение в команде `at`?

В bash расширение скобки выполняется как операция оболочки перед выполнением команды. 1 Это означает, что следующее будет работать:
echo {1..10} >output | at -m now

Выход будет 1 2 3 4 5 6 7 8 9 10 .

То, что не работает, – попытка выполнить расширение скобки внутри команды, которая предупреждает, что команды будут выполняться /bin/sh , что в моем случае связано с dash которая, похоже, не поддерживает расширение диапазона с помощью фигурных скобок.

 $ at - now warning: commands will be executed using /bin/sh at> echo {1..10} >output at> <EOT> 

Это запустит команду в dash (или Bourne или в какой-либо другой оболочке, к которой вы привязаны /bin/sh ), что приводит к результату {1..10} .

Как может быть выполнено расширение при использовании команды at таким образом?


Мне интересно видеть другие решения для этого, кроме того, что я опубликовал в качестве ответа, например, возможность выполнять команды с bash изнутри приглашения. Кажется, что требуется больше усилий, чем необходимо для создания сценария для каждой отдельной строки, запускаемой из приглашения.

Есть три простых варианта. Один из них немного хрупкий и опирается на детали реализации оболочек, другой использует здесь документы, чтобы предоставить скрипту bash inline, а другой просто использует -c для передачи одной строки.


Наиболее надежно и портативно использовать здесь документ :

 $ at now warning: commands will be executed using /bin/sh at> bash <<'EOF' at> echo {1..5} >/tmp/output at> EOF at> <EOT> job 24 at Mon Mar 23 20:41:20 2015 $ cat /tmp/output 1 2 3 4 5 

<<word объявляет здесь документ, который предоставляется в качестве стандартного ввода для bash и длится до word . Цитируя 'EOF' документ не подлежит расширению оболочкой, поэтому вы можете написать $ в теле без dash едящего его. В начале строки ваш скрипт может включать в себя что-либо, кроме EOF (или ваше слово выбора).

Это действительно тот подход, который я бы рекомендовал – вы можете почти написать его точно так же, как если бы вы все время использовали bash , а просто добавили строку в начале и в конце, чтобы показать, что что-то происходит.


Если это действительно единственная строка, просто используйте bash -c чтобы передать одну команду для запуска:

 $ at now warning: commands will be executed using /bin/sh at> bash -c 'echo {1..3} >/tmp/output' at> <EOT> job 25 at Mon Mar 23 20:50:03 2015 $ cat /tmp/output 1 2 3 

Это может быть немного хлопот, когда у вас есть котировки для использования внутри команды.


Наиболее хакерски: atd обычно отправляет задания в оболочку в качестве стандартного ввода (но я не считаю, что это необходимо). Оболочки обычно читают стандартный ввод строки за строкой (но они не обязаны вести себя таким образом).

Если ваши реализации ведут себя так, то вы можете выполнить неприятный трюк, чтобы запустить свою работу под другой оболочкой:

 $ at now warning: commands will be executed using /bin/sh at> bash at> echo {1..10} >/tmp/output at> <EOT> job 22 at Mon Mar 23 20:40:00 2015 $ cat /tmp/output 1 2 3 4 5 6 7 8 9 10 

Это работает, потому что sh считывает первую строку и выполняет bash , а bash затем считывает остальную часть стандартного ввода в качестве своих команд. Это довольно хрупко, но это наименее интрузивная версия, когда она работает.

Сама черта в этой области заметно затруднена, чем многие оболочки, и для нее важнее заполнение внутреннего буфера. Другие упрощенные оболочки, такие как BusyBox's sh , имеют тенденцию иметь поведение буферизации линии.


Наконец, хотя вам никогда не требуется использовать отдельный файл сценария, во многих случаях это будет лучший вариант, а не попытка быть слишком умным в отношении вещей. Когда ваши задания одноразовые или программно сгенерированы, это разумные варианты, но в любой другой момент сосать его и использовать автономный скрипт, вероятно, стоит того, чтобы его поддерживать.

Я действительно не могу рекомендовать использование stdin последнего варианта вообще, но это симпатичный трюк.

Единственное решение, которое я нашел до сих пор, это написать скрипт (назовем его expandme.sh), который указывает использование bash в качестве интерпретатора.

 #!/bin/bash echo {1..10} >output 

Затем запустите сценарий из приглашения:

 $ at - now warning: commands will be executed using /bin/sh at> expandme.sh at> <EOT> 

Теперь скрипт вытащит нас из ссылки в dash / Bourne чтобы мы ввели нас и выполнили расширение до сброса вывода.