Я пытаюсь получить bash для обработки данных со стандартного ввода, которые попадают в канал, но не повезло. Я имею в виду не одну из следующих работ:
echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=
echo "hello world" | read test; echo test=$test
test=
echo "hello world" | test=`cat`; echo test=$test
test=
где я хочу вывод test=hello world
. Я пытался поместить "" цитаты вокруг, "$test"
что тоже не работает.
shopt -s lastpipe
- tldp.org/LDP/abs/html/bashver4.html#LASTPIPEOPTОтветы:
использование
Вы можете обмануть
read
приемку из трубы следующим образом:или даже написать такую функцию:
Но нет смысла - ваши переменные могут не сохраняться! Конвейер может порождать подоболочку, где среда наследуется по значению, а не по ссылке. Вот почему
read
не беспокоит ввод из канала - он не определен.К вашему сведению, http://www.etalabs.net/sh_tricks.html - это отличная коллекция, необходимая для борьбы со странностями и несовместимостью борновых оболочек, ш.
источник
test=`echo "hello world" | { read test; echo $test; }`
{}
вместо()
группировки этих двух команд?read
сделать входные данные из канала, а в том, чтобы использовать переменную в той же оболочке, которая выполняетread
.bash permission denied
при попытке использовать это решение. Мой случай совершенно другой, но я не мог найти ответ на него в любом месте, что работает для меня было (другой пример , но подобное использование):pip install -U echo $(ls -t *.py | head -1)
. В случае, если кто-то когда-либо сталкивался с подобной проблемой и наткнулся на этот ответ, как я.если вы хотите читать много данных и работать с каждой строкой отдельно, вы можете использовать что-то вроде этого:
если вы хотите разбить строки на несколько слов, вы можете использовать несколько переменных вместо x следующим образом:
альтернативно:
Но как только вы захотите сделать что-то действительно умное с такими вещами, вам лучше перейти на некоторый язык сценариев, такой как perl, где вы можете попробовать что-то вроде этого:
Существует довольно крутая кривая обучения с Perl (или я предполагаю, что любой из этих языков), но в долгосрочной перспективе вам будет намного проще, если вы захотите сделать что-нибудь, кроме самых простых скриптов. Я бы порекомендовал Perl Cookbook и, конечно же, язык программирования Perl Larry Wall et al.
источник
read
не будет читать из канала (или, возможно, результат будет потерян, потому что канал создает подоболочку). Однако вы можете использовать здесь строку в Bash:Но см. Ответ @ chepner для получения информации о
lastpipe
.источник
Это еще один вариант
источник
<(..)
имеет более чем$(..)
является то , что<(..)
возвращает каждую строку к абоненту , как только команда , что она выполняет делает его доступным.$(..)
однако ожидает завершения команды и генерации всех ее выходных данных, прежде чем она сделает любой вывод доступным для вызывающей стороны.Я не эксперт в Bash, но мне интересно, почему это не было предложено:
Однострочное доказательство того, что у меня работает:
источник
bash
4.2 вводитlastpipe
опцию, которая позволяет вашему коду работать так, как написано, выполняя последнюю команду в конвейере в текущей оболочке, а не в подоболочке.источник
Синтаксис неявного канала из команды оболочки в переменную bash:
или
В ваших примерах вы передаете данные в оператор присваивания, который не ожидает ввода.
источник
Первая попытка была довольно близка. Этот вариант должен работать:
и вывод:
Вам нужны фигурные скобки после трубы, чтобы заключить назначение для проверки и эхо.
Без фигурных скобок присвоение test (после канала) находится в одной оболочке, а echo "test = $ test" находится в отдельной оболочке, которая не знает об этом назначении. Вот почему вы получили «test =» в выводе вместо «test = hello world».
источник
На мой взгляд, лучший способ чтения из stdin в bash - это следующий способ, который также позволяет вам работать со строками до окончания ввода:
источник
Поскольку я влюбляюсь в это, я хотел бы оставить записку. Я нашел этот поток, потому что мне нужно переписать старый скрипт sh, чтобы он был POSIX-совместимым. Это в основном означает обойти проблему pipe / subshell, представленную POSIX, переписав код следующим образом:
в:
И код так:
в:
Но последний не ведет себя так же при пустом вводе. В старой нотации цикл while не вводится при пустом вводе, но в нотации POSIX это так! Я думаю, что это связано с символом новой строки перед EOF, который нельзя пропустить. Код POSIX, который ведет себя больше как старая нотация, выглядит следующим образом:
В большинстве случаев это должно быть достаточно хорошо. Но, к сожалению, это все еще ведет себя не совсем так, как старые записи, если some_command выводит пустую строку. В старой нотации выполняется тело while, а в нотации POSIX мы разбиваемся перед телом.
Подход, чтобы исправить это, может выглядеть так:
источник
Интеллектуальный скрипт, который может считывать данные из PIPE и аргументы командной строки:
Вывод:
Объяснение: Когда скрипт получает какие-либо данные через канал, stdin / proc / self / fd / 0 будет символической ссылкой на канал.
Если нет, он будет указывать на текущий терминал:
Опция bash
[[ -p
может проверить, что это труба или нет.cat -
читает отstdin
.Если мы используем,
cat -
когда нетstdin
, он будет ждать вечно, поэтому мы помещаем его вif
условие.источник
/dev/stdin
ссылку на/proc/self/fd/0
Вложение чего-либо в выражение, включающее присваивание, не ведет себя так.
Вместо этого попробуйте:
источник
Следующий код:
тоже будет работать, но откроет еще одну новую под-оболочку после канала, где
не будет.
Мне пришлось отключить управление заданиями, чтобы использовать метод chepnars (я запускал эту команду из терминала):
Руководство Bash говорит :
Примечание: управление заданиями по умолчанию отключено в неинтерактивной оболочке, и поэтому вам не нужен
set +m
внутренний скрипт.источник
Я думаю, что вы пытались написать сценарий оболочки, который мог бы принимать ввод от стандартного ввода. но пока вы пытаетесь сделать это встроенным образом, вы заблудились, пытаясь создать эту переменную test =. Я думаю, что нет смысла делать это встроенным, и поэтому он не работает так, как вы ожидаете.
Я пытался уменьшить
чтобы получить конкретную строку из различных входных данных. чтобы я мог набрать ...
поэтому мне нужна небольшая программа оболочки, способная читать из стандартного ввода. как ты.
вот и ты.
источник
Как насчет этого:
источник