Debian недавно перешёл на использование network-manager в качестве способа конфигурирования сетевых интерфейсов по умолчанию. Либо настройте сеть с помощью network-manager, либо убедитесь, что /etc/init.d/networking будет вызван в последовательности запуска init, иначе содержимое /etc/network/interfaces не будет иметь значения.
Выполните ls -l /etc/rc[1-5].d/ | grep net
и убедитесь, что вы видите что-то вроде следующего:
lrwxrwxrwx 1 root root 25 Oct 2 2014 S01networking -> ../init.d/networking
Если это подтвердится, посмотрите dmesg | grep eth0
, но замените eth0 именем сетевого адаптера на виртуальной машине. Сообщите о всех ошибках.
Если вы не видите ссылки на скрипт инициализации сети или видите вместо него network-manager, выполните следующие действия от имени root:
update-rc.d networking defaults
update-rc.d -f network-manager remove
Это позволит установить нужные символические ссылки в /etc/rc[1-6].d/
и отключить network-manager.
Чтобы вручную установить символическую ссылку, вы можете указать ей запуск на любом уровне выполнения 1-5. Например:
pushd /etc/rc1.d/ && ln -s ../init.d/networking S08networking && popd
for i in `seq 2 5` ; do push /etc/rc$i.d/ && ln -s ../init.d/networking S01networking && popd ; done
pushd /etc/rc6.d/ && ln -s ../init.d/networking K07networking && popd
pushd /etc/rc0.d/ && ln -s ../init.d/networking K07networking && popd
Чтобы вручную отключить network-manager сделайте:
rm /etc/rc*.d/S*network-manager
Это потому, что вам нужна оболочка, чтобы создать трубу или выполнить перенаправление. Обратите внимание, что cat
- это команда для конкатенации, не имеет смысла использовать ее только для одного файла.
cat file1.txt | xargs -I{} sh -c 'cat file2.txt | grep -e "$1"' sh {}
Не делать:
cat file1.txt | xargs -I{} sh -c 'cat file2.txt | grep -e {}'
так как это будет равносильно уязвимости инъекции команд. {}
будет расширен в аргументе кода для sh
и интерпретирован как код оболочки. Например, если бы в строке file1.txt
было $(reboot)
, это вызвало бы reboot
.
Ключ -e
(или вы также можете использовать --
) также важен. Без него у вас будут проблемы с regexps, начинающимися с --
.
Вы можете упростить вышеописанное, используя перенаправления вместо cat
:
< file1.txt xargs -I{} sh -c '< file2.txt grep -e "$1"' sh {}
Или просто передать имена файлов в качестве аргумента в grep
вместо использования перенаправлений, в этом случае вы можете даже отказаться от sh
:
< file1.txt xargs -I{} grep -e {} file2.txt
Вы также можете указать grep
искать все регексы сразу в одном вызове:
grep -f file1.txt file2.txt
Заметьте, однако, что в этом случае, это только один регексп для каждой строки file1. txt
, нет никакой специальной обработки кавычек, выполняемой xargs
.
xargs
по умолчанию рассматривает свой ввод как список пустых (в некоторых реализациях только пробел и табуляция, в других - любых символов из класса [:blank:]
текущей локали) или разделенных новой строкой слов, для которых можно использовать обратную косую черту, одинарные и двойные кавычки для экранирования разделителей (новая строка может быть экранирована только обратной косой чертой) или друг друга.
Например, при вводе типа:
'a "b'\" "bar baz" x\
y
xargs
без -I{}
команде будут переданы a "b"
, bar baz
и x
.
С -I{}
, xargs
получает одно слово в строке, но все же выполняет некоторую дополнительную обработку. Он игнорирует ведущие (но не последующие) пробелы. Пробелы больше не рассматриваются как разделители, но обработка кавычек все равно выполняется.
На приведенном выше xargs -I{}
передаст команде один a "b" foo bar x
аргумент. Также обратите внимание, что во многих системах, как того требует POSIX, это не будет работать, если длина слов превышает 255 символов. В общем, xargs -I{}
довольно бесполезен.
Если вы хотите, чтобы каждая строка передавалась дословно как аргумент команды, вы можете использовать расширение GNU xargs
-d '\n'
:
< file1.txt xargs -d '\n' -n 1 grep file2.txt -e
(здесь используется другое расширение GNU grep
, которое позволяет передавать опции после аргументов (при условии, что POSIXly correct не находится в окружении) или портативно:
sed "s/'/'\\\\\\''/g;s/.*/'&'/" file1.txt | xargs -n1 sh -c '
for line do
grep -e "$line" file2.txt
done' sh
Если вы хотите, чтобы каждое слово в file1. txt
(кавычки все еще распознаются), а не каждую строку (что также обойдет вашу проблему с пробелами в конце строки, если у вас все равно одно слово в строке), вы можете использовать xargs -n1
вместо -I
:
< file1.txt xargs -n1 sh -c '
for word do
grep -e "$word" file2.txt
done' sh
Чтобы удалить ведущие и последующие пробелы (но без обработки кавычек, которую делает xargs
), вы также можете сделать:
unset IFS # restore word splitting to its default
while read -r regexp; do
grep -e "$regexp" file2.txt
done < file1.txt
В зависимости от того, что вы пытаетесь сделать, вам может быть лучше полностью пропустить xargs
и вместо этого использовать следующее решение:
grep -f file1.txt file2.txt
Оно отличается от исходного команда (как только мы исправим ее, как в ответе Стефана Чазеласа) следующим образом:
file2.txt
, независимо от того, каким шаблонам они соответствуют. В вашей команде печатаются все строки, соответствующие первому шаблону, затем все строки, соответствующие второму, и так далее. -v
и -c
. Флаг -f
указан в POSIX и поэтому достаточно переносим.