Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Shell странности перенаправления ввода сценариев
Может ли кто-нибудь объяснить такое поведение? Бегущий:
#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
результаты в ничего не выход, а:
#!/bin/sh
echo "hello world" > test.file
read var1 var2 < test.file
echo $var1
echo $var2
производит ожидаемый результат:
hello
world
Не должен ли канал сделать за один шаг то, что перенаправление на test.file сделало во втором примере? Я попробовал один и тот же код с оболочками dash и bash и получил одинаковое поведение от обоих из них.
Недавним дополнением к параметру bash является параметр lastpipe , который позволяет последней команде в конвейере выполняться в текущей shell, а не в подрешетке, когда управление заданием отключено.
#!/bin/bash
set +m # Deactiveate job control
shopt -s lastpipe
echo "hello world" | read var1 var2
echo $var1
echo $var2
будет действительно выходной
hello
world
#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
не производит никакого вывода, потому что трубопроводы запускают каждый из своих компонентов внутри подрешетки. Дочерние ячейки наследуют копии переменных родительского shell, а не совместно используют их. Попробовать это:
#!/bin/sh
foo="contents of shell variable foo"
echo $foo
(
echo $foo
foo="foo contents modified"
echo $foo
)
echo $foo
Скобки определяют область кода, которая запускается в подрешетке, и $foo сохраняет свое исходное значение после изменения внутри них.
А теперь попробуй вот это:
#!/bin/sh
foo="contents of shell variable foo"
echo $foo
{
echo $foo
foo="foo contents modified"
echo $foo
}
echo $foo
Фигурные скобки предназначены исключительно для группировки, не создается подрешетка, и $foo, измененный внутри фигурных скобок, является тем же самым $foo, измененным вне их.
А теперь попробуй вот это:
#!/bin/sh
echo "hello world" | {
read var1 var2
echo $var1
echo $var2
}
echo $var1
echo $var2
Внутри фигурных скобок read builtin создает $var1 и $var2 правильно, и вы можете видеть, что они получают Эхо. Вне скобок они больше не существуют. Весь код внутри фигурных скобок был запущен в подрешетке, потому что это один из компонентов конвейера .
Вы можете поместить произвольное количество кода между фигурными скобками, поэтому вы можете использовать эту конструкцию piping-into-a-block всякий раз, когда вам нужно запустить блок сценария shell, который анализирует выходные данные чего-то другого.
На этот вопрос уже дан правильный ответ, но решение пока не сформулировано. Используйте ksh, а не bash. Сравнивать:
$ echo 'echo "hello world" | read var1 var2
echo $var1
echo $var2' | bash -s
К:
$ echo 'echo "hello world" | read var1 var2
echo $var1
echo $var2' | ksh -s
hello
world
ksh-это превосходное Программирование shell из-за таких маленьких тонкостей, как эта. (На мой взгляд, bash-это лучший интерактивный shell.)
Ну ладно, я все понял!
Это трудная ошибка, чтобы поймать,но результаты от того, как трубы обрабатываются shell. Каждый элемент конвейера работает в отдельном процессе. Когда команда read устанавливает var1 и var2, is устанавливает их в свою собственную подрешетку, а не в родительскую shell. Таким образом, когда подрешетка выходит, значения var1 и var2 теряются. Однако вы можете попробовать сделать это
var1=$(echo "Hello")
echo var1
который возвращает ожидаемый ответ. К сожалению, это работает только для отдельных переменных, вы не можете установить много одновременно. Чтобы установить несколько переменных одновременно, вы должны либо прочитать одну переменную и разделить ее на несколько переменных, либо использовать что-то вроде этого:
set -- $(echo "Hello World")
var1="$1" var2="$2"
echo $var1
echo $var2
Хотя я признаю, что это не так элегантно, как использовать трубу, это работает. Конечно, вы должны иметь в виду, что read предназначался для чтения из файлов в переменные, поэтому сделать это чтение из стандартного ввода должно быть немного сложнее.
На этот пост был дан правильный ответ, но я хотел бы предложить альтернативный лайнер, который, возможно, может быть полезен.
Для назначения разделенных пробелами значений из echo (или stdout, если уж на то пошло) переменным shell можно использовать массивы shell:
$ var=( $( echo 'hello world' ) )
$ echo ${var[0]}
hello
$ echo ${var[1]}
world
В этом примере var-это массив, и доступ к содержимому можно получить с помощью конструкции ${var[index]}, где index-индекс массива (начинается с 0).
Таким образом, вы можете иметь столько параметров, сколько хотите, назначенных соответствующему индексу массива.
Это происходит потому, что версия канала создает подрешетку, которая считывает переменную в ее локальное пространство, которое затем уничтожается при выходе из подрешетки.
Выполните эту команду
$ echo $$;cat | read a
10637
и используйте pstree-p, чтобы посмотреть на запущенные процессы, вы увидите дополнительный shell, висящий на вашем основном shell.
| |-bash(10637)-+-bash(10786)
| | `-cat(10785)
Попробуй:
echo "hello world" | (read var1 var2 ; echo $var1 ; echo $var2 )
Проблема, как утверждали многие люди, заключается в том, что var1 и var2 создаются в среде подрешетки, которая разрушается при выходе из этой подрешетки. Вышеизложенное позволяет избежать разрушения подрешетки до тех пор, пока результат не будет Эхо-сигналом. :
result=`echo "hello world"`
read var1 var2 <<EOF
$result
EOF
echo $var1
echo $var2