Ключевые слова:sed, debian, network, config, shell, example, (найти похожие документы)
From: Тарасов Антон aka Ant0 <mailbox@ant0.ru.>
Date: Mon, 20 Oct 2006 14:31:37 +0000 (UTC)
Subject: Редактирование /etc/network/interfaces в Debian средствами sed
Оригинал: http://ant0.ru/sed_edit_interfaces.html
Тарасов Антон aka Ant0
Версия 1.1 от 15 Июня 2006
Составлено: Тарасов Антон aka Ant0 ([email protected])
В некоторых системных скриптах хотелось бы иметь возможность работы с
конфигом сетевых интерфесов.
Конфиг сетевых интерфейсов в Debian имеет примерно следующий вид:
$ cat /etc/network/interfaces
auto lo eth0 eth1
iface lo inet loopback
iface eth0 inet static
address 192.168.0.13
netmask 255.255.255.0
gateway 192.168.0.1
iface eth1 inet static
address 192.168.1.13
netmask 255.255.255.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Если работать только средствами sh (не говоря о языках более низкого
уровня), то получаеться громоздкий, ресурсоемкий и сложный для
написания и отладки код.
Ниже предлагаю "простенькие" скрипты на sed'е, для типичных операций:
Удаление интерфеса.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса передается
в параметре):
1. #!/bin/sh
2. [ -z "$1" ] && exit 1
3. sed -n "/auto/s/$1 \?//;/iface $1/{:x;n;/iface/by;bx;};:y;p" /etc/network/interfaces
Более подробно на примере sed скрипта:
1. #!/bin/sed -nf
2. # удаляю интерфейс из автоподнимаемых (ищу строку начинающуюся со
# слова auto, в ней ищу имя интерфейса (с пробелом или без) и
# вырезаю его):
3. /auto/s/eth0 \?//
4. #### далее удаление интерфейса и его параметров ####
5. #если строка содержит имя интерфейса, выполняю группу действий:
6. /iface eth1/{
7. #метка:
8. :x
9. #беру на анализ следующую строку (тем самым пропуская вывод этой):
10. n
11. #если начался следующий интерфейс, значит достигнут конец этого
интерфейса - перехожу на метку "y":
12. /iface/by
13. #перехожу на метку "x" (для удаления остальных параметров этого
интерфейса):
14. bx
15. }
16. #метка:
17. :y
18. #вывожу текущую строку на печать:
19. p
В результате работы sh скрипта:
$ ./del_iface eth0
auto lo eth1
iface lo inet loopback
iface eth1 inet static
address 192.168.1.13
netmask 255.255.255.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Еще вариант, хоть и более медленный и более сложный для понимания, но
отображает другой подход:
1. #!/bin/sed -f
2. #прерываю анализ строки, пока не найду строку содержащей имя интерфейса
3. /^iface eth0/!b
4. #удаляю iface чтобы не мешался:
5. s/iface //g
6. #метка:
7. :x
8. #если еще не дошел до следующего интерфейса, то:
9. /iface/!{
10. #прилепляю следующую строку к концу этой:
11. N
12. #перехожу на метку "x":
13. bx
14. }
15. #удаляю все остатки про этот интерфейс:
16. s/^eth1 .*iface/iface/
Удаление параметра интерфеса.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса и удаляемый
параметр передаются параметрами):
1. #!/bin/sh
2. [ -z "$1" -o -z "$2" ] && exit 1
3. sed "/iface $1/!b;:x;n;/$2/d;/iface/b;bx" /etc/network/interfaces
Более подробно на примере sed скрипта:
1. #!/bin/sed -f
2. #пока не найду нужный интерфейс прерываю обработку:
3. /iface eth0/!b
4. #метка:
5. :x
6. #беру на анализ следующую строку:
7. n
8. #ищу параметр и в случае успеха удаляю строку:
9. /address/d
10. #если дошел до следующего интерфейса, значит такого параметра нет
- прерываю обработку:
11. /iface/b
12. #перехожу на метку "x" (пока не найду нужный параметр):
13. bx
Еще вариант, хоть и более медленный и более сложный для понимания, но
отображает другой подход:
1. #!/bin/sed -nf
2. #если строка содержит имя интерфейса, выполняю группу действий:
3. /iface eth0/{
4. #метка:
5. :x
6. #вывожу текущую строку на печать:
7. p
8. #беру на анализ следующую строку:
9. n
10. #если это строка с параметром, то прерываю анализ строки - тем
#самым не выводя на печать искомый параметр
11. /address/b
12. # если начался следующий интерфейс, значит такого параметра нет -
# перехожу на метку "y":
13. /iface/by
14. #перехожу на метку "x" (для удаления остальных параметров этого интерфейса):
15. bx
16. }
17. #метка:
18. :y
19. #вывожу текущую строку на печать:
20. p
Если скрипту передать имя интерфейса как eth, то удалиться заданный
параметр у всех интерфейсов eth (eth0, eth1 и т.д.). Пригодиться, к
примеру, для удаления шлюза по умолчанию (gateway).
В результате работы sh скрипта:
$ ./del_param_iface eth0 address
auto lo eth0 eth1
iface lo inet loopback
iface eth0 inet static
netmask 255.255.255.0
gateway 192.168.0.1
iface eth1 inet static
address 192.168.1.13
netmask 255.255.255.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Замена параметра интерфеса.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса, заменяемый
параметр и значение передаются параметрами):
1. #!/bin/sh
2. [ -z "$1" -o -z "$2" -o -z "$3" ] && exit 1
3. sed "/iface $1/!b;:x;n;s/$2.*/$2 $3/;t;/iface/b;bx"
/etc/network/interfaces
Более подробно на примере sed скрипта:
1. #!/bin/sed -f
2. #пока не найду нужный интерфейс прерываю обработку:
3. /iface eth0/!b
4. #метка:
5. :x
6. #беру на анализ следующую строку:
7. n
8. #ищу в строке нужный параметр и заменяю его
9. s/netmask.*/netmask 255.255.255.0/
10. # в случае успешного выполнения предыдушей операции прерываю обработку:
11. t
12. #если дошел до следующего интерфейса, значит такого параметра нет
- прерываю обработку:
13. /iface/b
14. #перехожу на метку "x" (пока не найду нужный параметр):
15. bx
В результате работы sh скрипта:
$ ./sub_param_iface eth1 address 192.168.3.1
auto lo eth0 eth1
iface lo inet loopback
iface eth0 inet static
address 192.168.0.13
netmask 255.255.255.0
gateway 192.168.0.1
iface eth1 inet static
address 192.168.3.1
netmask 255.255.255.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Добавление параметра интерфеса.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса,
добавляемый параметр и значение передаются параметрами):
1. #!/bin/sh
2. [ -z "$1" -o -z "$2" -o -z "$3" ] && exit 1
3. sed "/iface $1/s/$/\n\t$2 $3/" /etc/network/interfaces
Здесь: если строка содержит имя интерфейса, то в конец строки добавляю
символ новой строки "\n" и добавляемый параметр со значением
В результате работы sh скрипта:
$ ./add_param_iface eth1 network 192.168.3.0
auto lo eth0 eth1
iface lo inet loopback
iface eth0 inet static
address 192.168.0.13
netmask 255.255.255.0
gateway 192.168.0.1
iface eth1 inet static
address 192.168.3.1
netmask 255.255.255.0
network 192.168.3.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Добавление параметра интерфеса (продвинутый вариант).
Анализирую конфиг на предмет существования этого параметра и если он
есть, то заменяю его значение, иначе создаю параметр со значением.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса,
добавляемый параметр и значение передаются параметрами):
1. #!/bin/sh
2. [ -z "$1" -o -z "$2" -o -z "$3" ] && exit 1
3. sed "/iface $1/!b;:x;n;s/$2.*/$2
$3/;t;/^[[:space:]]*$/{N;s/\n//;};/iface/s/^/\t$2 $3\n\n/;t;bx"
/etc/network/interfaces
Более подробно на примере sed скрипта:
1. #!/bin/sed -f
2. #пока не найду нужный интерфейс прерываю обработку:
3. /iface eth1/!b
4. #метка:
5. :x
6. #беру на анализ следующую строку:
7. n
8. #если нашел параметр, то заменяю его значение:
9. s/address.*/address 123.123.123.123/
10. #в случае успешной предыдущей операции прервыю обработку:
11. t
12. #если пустая строка
13. /^[[:space:]]*$/{
14. #прилепляю конец следующей к этой
15. N
16. #удаляю \n
17. s/\n//
18. }
19. #если дошел до следующего интерфейса, значит такого параметра нет
- добавляю параметр и значение:
20. /iface/s/^/\taddress 123.123.123.123\n\n/
21. #в случае успешной предыдущей операции прервыю обработку:
22. t
23. #перехожу на метку "x" (пока не найду нужный параметр):
24. bx
Еще вариант. Мне он нравится больше:
1. #!/bin/sed -nf
2. #пока не найду нужный интерфейс перехожу на метку "y":
3. /iface eth1/!by
4. #метка:
5. :x
6. #вывожу текущую строку на печать:
7. :p
8. #беру на анализ следующую строку:
9. n
10. #если нашел параметр, то заменяю его значение:
11. s/address.*/address 123.123.123.123/
12. #в случае успешной предыдущей операции перехожу на метку "y":
13. ty
14. #если пустая строка, то пропускаю ее вывод
15. /^[[:space:]]*$/n
16. #если дошел до следующего интерфейса, значит такого параметра нет
- добавляю параметр и значение:
17. /iface/s/^/\taddress 123.123.123.123\n\n/
18. #в случае успешной предыдущей операции перехожу на метку "y":
19. ty
20. #перехожу на метку "x" (пока не найду нужный параметр):
21. bx
22. #метка:
23. :y
24. #вывожу текущую строку на печать:
25. :p
В результате работы sh скрипта:
$ ./add_param_iface eth1 network 192.168.3.0
auto lo eth0 eth1
iface lo inet loopback
iface eth0 inet static
address 192.168.0.13
netmask 255.255.255.0
gateway 192.168.0.1
iface eth1 inet static
address 192.168.3.1
netmask 255.255.255.0
network 192.168.3.0
iface ath0 inet static
address 192.168.2.13
netmask 255.255.255.0
wireless-essid home
wireless-nick Notebook
wireless-channel 1
wireless-ap 00:14:86:AC:5A:FA
wireless-rate 54M
Получить значение параметра интерфеса.
sed скрипт в одну строку в теле sh скрипта (имя интерфейса и
запрашиваемый параметр передаются параметрами):
1. #!/bin/sh
2. [ -z "$1" -o -z "$2" ] && exit 1
3. sed "/iface $1/!b;:x;n;/$2/p;/iface/b;bx" /etc/network/interfaces
Более подробно на примере sed скрипта:
1. #!/bin/sed -nf
2. #пока не найду нужный интерфейс прерываю обработку
3. /iface eth1/!b
4. #метка:
5. :x
6. #беру на анализ следующую строку:
7. n
8. #если нашел параметр, то печатаю его:
9. /address/p
10. #другой вариант вместо предыдущей строчки - печатает только
#параметр (вариант 1):
11. #/address/s/^[[:space:]]*address \(.*\)/\1/p
12. #или еще быстрее (вариант 2):
13. #/address/s/^[[:space:]]*address //p
14. #если дошел до следующего интерфейса, то прерываю обработку:
15. /iface/b
16. #перехожу на метку "x" (пока не найду нужный параметр):
17. bx
В результате работы sh скрипта:
$ ./get_param_iface eth1 address
address 192.168.3.1
В результате работы sh скрипта (в вариантах 1 и 2):
$ ./get_param_iface eth1 address
192.168.3.1
Получить список всех интерфейсов определенного типа.
sed скрипт в одну строку в теле sh скрипта (тип передаются
параметром):
1. #!/bin/sh
2. [ -z "$1" ] && exit 1
3. sed -n "/iface .* $1/s/ifac \([a-z0-9]*\) .*/\1/p" /etc/network/interfaces
Здесь: если строка содержит небходимый тип интерфейса, то вырезаю имя
интерфейса и вывожу его на печать.
В результате работы sh скрипта:
$ ./get_iface_by_type static
eth0 eth1 ath0
Данные скрипты применялись в embedded-девайсах, т.е. там где нет возможности править конфиги ручками (законченная железяка) и уж тем более там нет nano....
скрипты - зло. не понимаю повсеместного увлечение этим детским вариантом программирования. От написания этих скриптов до написания консольной или графической утилиты один шаг.
бугага! :)))
эти "детские" скрипты работают в железяках конечной стоимостью от нескольких сотен, до нескольких тысяч баксов - работают стабильно, быстро, надежно и замечательно раскупаются! :)))
а железо - от ARM200Mhz,4Mb RAM,8Mb FLASH и мощьнее.
успехов засунуть туда мышко-тыкательный интерфейс! :)
ну можно конечно все на С-ях писать, но не в этом случае.... :)
Как мне подсказал Павел Кудряшов (большой ему за это спасибо): в данной статье, к сожалению, много ошибок и неточностей - которые появились, по всей видимости, при копировании с оригинала...
Пропущены слешы, неправильно написаны некоторые слова и пр - отчего часть скриптов просто не работоспособна!!!
Если что-то не работает, обращайтесь пожалуйста к первоисточнику или ко мне в аську/жаббер (контакты есть на моем сайте).