Bash получить команду, которая транслируется в скрипт - PullRequest
0 голосов
/ 27 мая 2019

Возьмите следующий пример:

ls -l | grep -i readme | ./myscript.sh

Я пытаюсь получить ls -l | grep -i readme в виде строковой переменной в myscript.sh. По сути, я пытаюсь получить всю команду перед последним каналом для использования внутри myscript.sh.

Возможно ли это?

Ответы [ 4 ]

3 голосов
/ 27 мая 2019

Нет, это невозможно.

На уровне ОС конвейеры реализуются с помощью системных вызовов mkfifo(), dup2(), fork() и execve(). Это не обеспечивает способ сообщить программе, какие команды связаны с ее стандартным вводом. Действительно, не гарантируется, что будет строкой, представляющей конвейер программ, используемых для генерациивообще stdin, даже если ваш stdin действительно FIFO, подключенный к stdout другой программы;может случиться так, что этот конвейер был сгенерирован программами, вызывающими execve() и непосредственно друзьями.

Лучший доступный обходной путь - это инвертировать ваш процесс.

Это не то, что вы просили, но этото, что вы можете получить.

#!/usr/bin/env bash
printf -v cmd_str '%q ' "$@"  # generate a shell command representing our arguments

while IFS= read -r line; do
  printf 'Output from %s: %s\n' "$cmd_str" "$line"
done < <("$@")       # actually run those arguments as a command, and read from it

... а затем ваш скрипт start , из которого он читает, вводит данные, а не получает их на стандартный ввод.

...после того, ./yourscript ls -l или ./yourscript sh -c 'ls -l | grep -i readme'.(Конечно, никогда не используйте это, кроме как в качестве примера; см. ParsingLs ).

2 голосов
/ 27 мая 2019

Обычно этого нельзя сделать, но с помощью команды history в bash можно выполнить сортировку при условии соблюдения определенных условий:

  • history должно быть включено.

  • С момента запуска myscript.sh . * Только одна оболочка выполняла или принимала новые команды (или не выполняла ее, запуская myscript.sh ). 1018 *

  • Поскольку командные строки с начальными пробелами по умолчанию не сохраняются в истории, команда вызова для myscript.sh не должна иметь начальных пробелов; или это значение по умолчанию должно быть изменено - см. Получить историю Bash, чтобы запомнить только команды, выполняемые с префиксом .

  • Вызывающая команда должна заканчиваться &, потому что без нее новая командная строка не будет добавлена ​​в историю до тех пор, пока myscript.sh не будет завершено.

Сценарий должен быть bash, (он не будет работать с /bin/dash), а вызывающая оболочка требует небольшой подготовительной работы. Прежде чем запускать скрипт, выполните:

shopt -s histappend
PROMPT_COMMAND="history -a; history -n"

... это делает историю bash наследственной. (Код смахнул с unutbu на соответствующий вопрос .)

Тогда myscript.sh может идти:

#!/bin/bash
history -w
printf 'calling command was: %s\n' \
    "$(history | rev | 
       grep "$0" ~/.bash_history | tail -1)"

Тестовый прогон:

echo googa | ./myscript.sh &

Вывод, (за вычетом ассоциированного фрейта "&"):

calling command was: echo googa | ./myscript.sh &

Дробь можно уменьшить вдвое, изменив "&" на "& fg", но в результате вы не получите суффикс "fg".

0 голосов
/ 27 мая 2019

Я думаю, что это возможно, посмотрите на этот пример:

#!/bin/bash
result=""
while read line; do
  result=$result"${line}"
done
echo $result

Теперь запустите этот скрипт, используя канал, например:

ls -l /etc | ./script.sh

Я надеюсь, что это будетбыть полезным для вас:)

0 голосов
/ 27 мая 2019

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

./myscript.sh "$(ls -l | grep -i readme)"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...