Выполнение скриптов в терминале оболочки напрямую как stdin без наследуемых документов

Есть ли способ выполнять сценарии в терминале оболочки напрямую как стандартный ввод без исходных документов?

Я избегаю использования heredocument, потому что этот метод многими Bash-программистами считается архаичным и легко конфликтует с обычными оболочками и не косметическим в случае длинных строк heredoc, представленных в текстовых редакторах.


Мой текущий способ запуска сценариев заключается в выполнении следующей команды и вставке сценария внутрь:

nano ~/ses.sh && chmod +x ~/ses.sh && sh ~/ses.sh && rm ~/ses.sh

После вставки я сохраняю, а затем, когда я выхожу, сценарий выполняется.

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

Я ищу способ, который поддерживает отступы табуляции .

-2
23.04.2017, 17:21
3 ответа

Здесь-документы имеют преимущество в том, что сам скрипт может продолжаться после завершения здесь-документа. Если вам это не нужно, и вы просто хотите вставить скрипт для запуска оболочки вы можете обойти редактирование строки, сделав оболочку неинтерактивной, подключив stdin к чему-то другому, кроме терминала, или явно указав оболочке, откуда читать команды:

$ cat | sh              # or
$ sh /dev/stdin

Что-то вроде этого работает для меня тоже:

$ sh /dev/stdin
cat -n <<-EOF
[tab]foo
[tab]EOF
     1  foo
exit

Если ваш скрипт заканчивается exit , вам даже не нужно организовывать отправку ^ D для его завершения.

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

0
28.01.2020, 05:17

Вы можете передать серию команд (по крайней мере, некоторым оболочкам, которые специально обрабатывают- ), например,

sh - <<'EOF'
chmod +x ~/ses.sh || exit 1
sh ~/ses.sh || exit 1
rm ~/ses.sh
EOF

, хотя было бы неудобно запускать nanoв трубе.

Похоже, это не особенность оболочки POSIX, которая говорит только

Одиночный<дефис-минус>должен рассматриваться как первый операнд, а затем игнорируется. Если в качестве аргументов указаны как «-», так и «--», или если другие операнды предшествуют одиночному<дефис-минус>, результаты не определены.

Вы также можете записать это как

#!/bin/sh
{
echo "chmod +x ~/ses.sh"
echo "sh ~/ses.sh"
echo "rm ~/ses.sh"
} | sh -
0
28.01.2020, 05:17

Вы можете выполнить сценарий в терминале, вставив его напрямую. Это может быть неудобно, потому что вывод скрипта может в конечном итоге смешаться с тем, что вы вставляете, если только ваш термин и оболочка не поддерживают вставку в квадратных скобках. Без вставки в квадратных скобках вкладки также представляют собой проблему, потому что они представляют собой сочетание клавиш в интерактивных оболочках. Решение вашей проблемы с вкладками, конечно, не в использовании вкладок, а. паста в скобках полезна в любом случае. Bash поддерживает вставку только в квадратных скобках, начиная с версии 4.4. Современные версии xterm поддерживают вставку в квадратных скобках, я не знаю о других терминалах.

Запуск второй оболочки в терминале и передача сценария для запуска в качестве входных данных для второй оболочки через документ здесь в первой оболочке — один из способов избежать этого дефекта. Причины, по которым вы избегаете этого метода, таковы. Он не «архаичен» (ни в коей мере не устарел), он не конфликтует ни с одной общей оболочкой, и с ним нет косметических проблем (не то, чтобы это имело значение: вы никуда не кладете документ здесь, кроме окно терминала). Есть веская причина иногда избегать этого метода: вы передаете сценарий на стандартный ввод, поэтому вы не можете использовать стандартный ввод для чего-то еще. Это проблема только в том случае, если вы хотите использовать стандартный ввод из чего-то другого.

Если вы хотите запускать код из буфера обмена, лучшим решением будет указать вашей оболочке запустить код из буфера обмена. Однако это работает только в том случае, если у вас есть доступ к буферу обмена из оболочки. Если вы запускаете оболочку на виртуальной машине, убедитесь, что сквозная передача буфера обмена активна и что вы используете X-сервер внутри виртуальной машины (а не текстовую консоль). В качестве альтернативы используйте SSH для входа в виртуальную машину. Если вы используете SSH, убедитесь, что переадресация X11 включена, а если ваш локальный компьютер не является Unix, убедитесь, что ваш терминал имитирует его (в Windows это может означать запуск X-сервера, такого как Xming). Затем вы можете запустить шелл-код из буфера обмена с помощью

bash -c "$(xsel)"         # Selection, i.e. text copied by selecting with the mouse
bash -c "$(xsel -b)"      # Clipboard, i.e. text copied with Ctrl+C
bash -c "$(pbpaste)"      # macOS
0
28.01.2020, 05:17

Теги

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