Пробовал использовать Python, все работает нормально
#!/usr/bin/python
import re
g=re.compile(r'[0-9]*\.[0-9]*\.[0-9]*')
m=open('u.txt','r')
for i in m:
if re.search(g,i):
print i.strip().replace("#","")
вывод 1
92.168.54.144 name1
192.168.54.144 name2
192.168.54.143 name3
Во-первых, обратите внимание, что задействованы две оболочки. Есть внешний Bash, в котором вы работаете, вы вызываете в нем (тип )bash <(wget -O - URL)
. И есть внутренний Bash, который запускается как дочерний процесс внешнего Bash, когда команда выполняется.
Другими словами, внешний Bash принимает bash <(wget -O - URL)
как команду и порождает внутренний Bash. Я буду различать два, где это уместно.
Есть несколько способов заставить (внутренний )Bash запустить некоторый код:
bash
может читать код со своего стандартного ввода:
echo 'date; sleep 2; date' | bash
Стандартный ввод может быть консолью. Например. интерактивный bash
вы обычно работаете при чтении с консоли, но на самом деле он читает со своего стандартного ввода, потому что консоль является его стандартным вводом.
bash
может читать код из файла:
bash /path/to/some/file
(Путь может быть относительным.)
bash
может читать код из аргумента строки команды -:
bash -c 'date; sleep 2; date'
В комментарии вы сказали, что контекст этот вопрос . Мой ответ там посоветовал заменить:
wget -O - URL | bash
с
bash <(wget -O - URL)
Первая команда заставляет внутренний bash
читать из стандартного ввода. Что вы, кажется, не поняли, так это то, что вторая команда заставляет внутренний bash
читать из файла, который не является его стандартным вводом.
<(…)
Когда вы запускаете bash <(wget -O - URL)
в Bash, внешний Bash заменяет <(…)
путем к какому-то файлу . После замены фактическая выполняемая команда может выглядеть как:
bash /dev/fd/63
Это порождает внутренний Bash. Он открывается /dev/fd/63
так же, как открывается /path/to/some/file
.
Благодаря «волшебству» подстановки процесса /dev/fd/63
— это канал, уже подключенный к wget -O - URL
.
Примечание :в системе, где /dev/fd
недоступен, внешний Bash будет использовать действительно именованный канал (, например. /tmp/sh-np.pldKay
), чтобы настроить это.
Соединение от wget
к (внутреннему)bash
аналогично в обоих случаях. Когда вы запускаете wget -O - URL | bash
, bash
считывает код со своего стандартного ввода, который является каналом, в который wget
записывает. Когда вы запускаете bash <(wget -O - URL)
, bash
читает код из другого файла (, то есть не из его стандартного ввода ), который является каналом wget
. В обоих случаях внешний Bash устанавливает канал.
Разница в том, что при подстановке процесса стандартный ввод внутреннего Bash не используется для передачи ему кода. Стандартный ввод можно использовать для другой цели. Например. стандартный ввод может быть консолью, и read
в коде может читать из нее.
What problem/s this concept was invented to solve
Когда команда ожидает имя пути (путь к файлу )и вы хотите передать что-то вместо предоставления обычного файла, вы можете создать именованный канал и достичь цели. Для этого нужно фактически создать канал (mkfifo
), подключить к нему что-то (в фоновом режиме или в другой консоли ), запустить команду и, наконец, удалить именованный канал(rm
).
При замещении процесса Bash обрабатывает конвейер. Это удобно.
What process is being substituted and with what?
В bash <(wget -O - URL)
синтаксис <(wget -O - URL)
заменяется на путь к какому-то файлу, только потом выполняется команда (и она bash /dev/fd/63
или аналогичная ). Внешний Bash подготавливает файл, поэтому чтение из него означает чтение того, чтоwget -O - URL
(пишет процесс ). Файл на самом деле является каналом, а не обычным файлом.
Is it also named "preserving stdin" and if so why?
«Сохранение стандартного ввода» происходит, но это не альтернативное имя для подстановки процесса. Это не формальное название того, что происходит.
Когда вы запускаете (inner)bash …
в (external )Bash, внутренний Bash получает свой stdin, унаследованный от внешнего Bash (, то есть это тот же файл ). Стандартный ввод может быть консолью.
Но если вы вместо этого запустите wget … | bash …
, внутренний Bash увидит данные из wget
на своем собственном стандартном вводе. Теперь некоторая часть внутреннего Баша (, например. встроенныйread
)или какой-либо дочерний элемент внутреннего Bash может захотеть прочитать что-то из стандартного ввода. Они ожидают ввода с консоли или чего-то еще, но не код, который должен выполнять внутренний Bash. Но поскольку стандартный ввод внутреннего Bash является конвейером из wget
, встроенные функции будут использовать его, а дочерние процессы наследуют его как свои стандартные вводы. Они не наследуют стандартный ввод внешнего Bash.
Используя подстановку процесса вместо передачи кода через стандартный ввод (внутреннего )bash
, вы делаете стандартный ввод внешнего Bash доступным для встроенных и дочерних модулей внутреннего Bash. Вы сохраняете стандартный ввод внешнего Bash для встроенных и дочерних модулей внутреннего Bash. В то же время вы защищаете поток кода, который читает и выполняет внутренний Bash, от чтения его встроенными или дочерними элементами.
Это работает только потому, что bash
позволяет предоставить код в файле, указанном в качестве аргумента командной строки. Если бы (внутренний )Bash поддерживал чтение кода только из стандартного ввода, вам пришлось бы предоставлять код через его стандартный ввод. В таком случае замена процесса не может решить вашу проблему .