Перейти к содержимому

Конвейер после получения bashscript

0

у меня есть код

# Inside Child.sh ChildVariable=BigChild  # Inside Parent.sh source ./Child.sh  echo "ChildVariable=$" 

Выход:

ChildVariable=BigChild 

Но,

# Inside Parent.sh source ./Child.sh | sed 's/\(.*\)/\t\1/' echo "ChildVariable=$" 

Выход:

ChildVariable= 

Мне нужно сделать отступ для вывода (если есть), Child.shпоэтому мне нужно передать вывод в sed. Но я не понимаю, почему ChildVariableне установлено?

582 просмотра
Nikhil спросил 7 лет назад
N 115

1 ответ

2

От man 1 bash:

Каждая команда в конвейере выполняется как отдельный процесс (т. Е. В подоболочке).

Ты получаешь из подоболочки; переменная задается в подоболочке, а не в запущенной оболочке Parent.sh.

Это будет источник Child.shв правой оболочке:

# Inside Parent.sh source ./Child.sh > >(sed 's/\(.*\)/\t\1/') echo "ChildVariable=$" 

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

Вы помечено так sourceи замена процесса ( > >(…)) в порядке. Чтобы сделать это переносимым (-ish?), Нужно использовать .вместо негоsource и ввести некоторые трюки с fifos .

Спасибо! Не могли бы вы порекомендовать, как изменить дизайн этой программы, и я намереваюсь сделать вывод дочернего сценария с отступом от символа табуляции?

Nikhil · 7 лет назад · 0

Кроме того, в следующем cmd 1; cmd 2 | cnd 3 | cmd 4 все эти команды выполняются в другом процессе? Я думал, что как минимум cmd 1 и cmd 2 будут встречаться в одной оболочке.

Nikhil · 7 лет назад · 0

@Nikhil Это зависит от того, что он делает. Можете ли вы разделить его на две части? Я имею в виду одну часть, которая устанавливает переменные (с источником) и одну, которая генерирует вывод (не с источником).

Kamil Maciorowski · 7 лет назад · 0

@Nikhil cmd 1 будет запускаться текущей оболочкой, cmd 2 - в подоболочке. Возьмите ; и замените его символом новой строки - результат станет более очевидным.

Kamil Maciorowski · 7 лет назад · 0

a =" A "echo $ a A иa = "A"; echo $ a AЗдесь мы можем видеть, чтоa = "A"и echo $ a запускаются в одной оболочке независимо от точки с запятой или новой строки. Здесь разделенные пробелом команды выполняются в новой строке.

Nikhil · 7 лет назад · 0

@Nikhil Этого echo нет в трубе, это отличает его от cmd 2. Но даже если бы он был в конвейере (таким образом, работал в подоболочке), он напечатал бы значение переменной.

Kamil Maciorowski · 7 лет назад · 0
Kamil Maciorowski ответил 7 лет назад
K 22 826