LINUX.ORG.RU

Использование переменных в shell-программировании


1

1

Извините, что поднимаю тему, которая много раз было. Да, я в курсе что google на запрос «shell программиование» выдаёт много всего. Но вот что не понятно.

1. export - это команда, экспортирующая локальную переменную, после чего локальная переменная становится переменной окружения и будет доступна в других шеллах, запущеных под другими пользователями. Поэтому export должна запускаться под рутом, но посколько это внутренняя команда, то, чтобы запустить её через sudo, нужно это делать через отдельный шелл, то есть:

sudo bash -c 'export netplan=beeline'
Так почему же эта команда не срабатывает, пробовал после посмотреть список переменных окружения через set - netplan там не обнаружил.

2. Потом нужно, чтобы при определённом значении переменной добавлялись правила фаерволла:

#!/bin/bash
if [$netplan=beeline]
        then
                iptables -t filter -A INPUT -i eth0 -p icmp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p udp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -j REJECT
fi
В чём ошибка данного скрипта?

3. И наконец, под шеллом по умолчанию bash или sh подразумевается?

★★★★★

В чём ошибка данного скрипта?

В том что пункт 1 — полный бред.

anonymous ()

1. Где такое написано? После export переменная доступна всем приложениям, запускаемым в текущем шелле. 3. По умолчанию - тот, что прописан в /etc/passwd.

anonymous ()

1. Не нужно sudo. Просто напиши:

export netplan="beeline"

2. Ошибка в записи проверки условия. Надо так:

if [ $netplan = "beeline" ]

Примечание: особое внимание обрати на пробелы в записи условного выражения.

Дальше всё правильно.

3. Тот, который установлен для тебя (для твоего логина) по умолчанию (берётся из /etc/passwd). Можно узнать командой:

echo $SHELL

PS: Лучше всё-таки в заголовке скрипта писать:

#!/bin/sh

для универсальности.

DeVliegendeHollander ★★ ()
Последнее исправление: DeVliegendeHollander (всего исправлений: 1)
Ответ на: комментарий от anonymous

Где такое написано? После export переменная доступна всем приложениям, запускаемым в текущем шелле.

Значит я всё переврал, когда додумывал прочитанное? А какая тогда команда делает переменную доступной не только приложениям, запущеным в текущем шелле, но и во всех других шеллах?

sunny1983 ★★★★★ ()
Ответ на: комментарий от sunny1983

Значит я всё переврал, когда додумывал прочитанное?

Да

какая тогда команда делает переменную доступной […] во всех других шеллах

Нет такой, только для потомков. Для того, что бы переменные наследовались вмеми процессами, надо их указывать init'у или login'у.

beastie ★★★★★ ()
Ответ на: комментарий от sunny1983

переменную доступной не только приложениям, запущеным в текущем шелле, но и во всех других шеллах?

Это уже больше из области применения gconf или аналога.

anonymous ()
Ответ на: комментарий от DeVliegendeHollander

PS: Лучше всё-таки в заголовке скрипта писать:
#!/bin/sh
для универсальности

Все сюда,у нас здесь админ АЭС проводит мастер-класс

zolden ★★★★★ ()
Ответ на: комментарий от sunny1983

А какая тогда команда делает переменную доступной не только приложениям, запущеным в текущем шелле, но и во всех других шеллах?

На уровне системы - добавить экспорт в /etc/profile. Любой стартующий шелл будет в первую очередь выполнять этот скрипт.

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
schizoid ★★★ ()
Ответ на: комментарий от chenger

Я согласен, при миграции скриптов мониторинга температуры урановых стержней с FreeBSD на QNX универсальность это очень важно

zolden ★★★★★ ()
Ответ на: комментарий от zolden

Все равно не понимаю к чему тут урановые стержни. Речь идет об универсальности. Мало кому нужно, чтобы при смене дистрибутива, допустим, приходилось переписывать скрипты подключения к интернет. Ваши слова показывают, что Вы с этим не согласны, из чего я могу сделать вывод, что либо Вы тролль, либо петросян.

chenger ★★ ()
Ответ на: комментарий от chenger

я урановый Петросян, который знает конфигурацию каждого своего сервера и поэтому в жизни не имел проблем с совместимостью скриптов

zolden ★★★★★ ()
Ответ на: комментарий от justAmoment

Анализируя советы, решил:

1. Изменять /etc/profile во время работы системы как-то заморочно. Встанет проблема как возвращать изменения назад при изменении нетплана.

2. Если наследование переменных - только прямое и для полной глобализации переменных нужно изменять переменные инита, а как это сделать - в общем это тоже заморочно.

3. Останавливаюсь на сохранении переменной в /tmp.

bash -c 'echo beeline > /tmp/netplan'
#!/bin/sh
if [ `cat /tmp/netplan` = "beeline" ]
        then
                iptables -t filter -A INPUT -i eth0 -p icmp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p udp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -j REJECT
fi
Так верно?

sunny1983 ★★★★★ ()
Ответ на: комментарий от sunny1983

Нет.

echo "netplan=beeline" > /tmp/netplan
#!/bin/sh

. /tmp/netplan

if [ x"$netplan" = x"beeline" ]; then
                iptables -t filter -A INPUT -i eth0 -p icmp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p udp -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -j REJECT
fi

Так лучше.

akk ★★★★★ ()
Последнее исправление: akk (всего исправлений: 2)
Ответ на: комментарий от sunny1983

В лучших традициях лора ты описал придуманные тобой костыли, вместо того, чтобы описать стоящую перед тобой задачу.
Так дела не делаются

zolden ★★★★★ ()
Ответ на: комментарий от sunny1983

Лучше считывать из файла во внутренние переменные до начала сравнений, чтобы можно было делать несколько сравнений. Если хранить значения построчно, то брать предпоследнее и последнее значения.

#!/bin/sh
starttime=`tail -n 2 /tmp/netplan | head -1`
netplan=`tail -1 /tmp/netplan`
if [ "x"$netplan = "xbeeline" ]
        then
                iptables -t filter -A INPUT -i eth0 -p icmp -m comment --comment "$netplan $starttime" -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p tcp -m state --state RELATED,ESTABLISHED -m comment --comment "$netplan $starttime" -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -p udp -m comment --comment "$netplan $starttime" -j ACCEPT
                iptables -t filter -A INPUT -i eth0 -m comment --comment "$netplan $starttime" -j REJECT
fi

justAmoment ★★★★★ ()

Это же не программирование, а написание скриптов. Это не программы.

zhigan ()
Ответ на: комментарий от zolden

zolden

А действительно.

Компьютер представляет собой ноутбук, который часто переносится и подключается к различным сетям. Для этого в /etc/network есть несколько файлов конфигураций сети interfaces.mzrta, interfaces.Vanilla, interfaces.beeline; при переносе ноутбука с места на место файл конфигурации сети копируется на место /etc/network/interfaces. Дистрибутив, как понятно, Debian.

Ещё есть скрипт заполнения фаерволла /etc/network/if-up.d/load-iptables Для каждой сети нужны свои правила, например для домашней сети они не нужны, а вот находясь в Билайне порты всё-таки лучше закрыть. И, чтобы не городить также по скрипту на каждую сеть, скрипт создан всего один, но в нём есть условия по значению переменной. А переменная присваевается в файле конфигурации сети с помощью опции up, например:

auto lo wlan0
allow-hotplug wlan0

iface lo inet loopback

iface wlan0 inet dhcp
   wpa-ssid Vanilla
   wpa-psk ChervyachniyReductor
   up bash -c 'echo "Vanilla" > /tmp/netplan'

sunny1983 ★★★★★ ()
Ответ на: комментарий от zolden

Да, я зря сюда со своим свиным рылом и дурацкими советами влез в компанию «супер-золденов». Извини, чёрный брат, больше не буду.

DeVliegendeHollander ★★ ()
Ответ на: комментарий от sunny1983

Так правильно, только при условии, что в /tmp/netplan может быть одно слово. В целом рабочее решение, но не очень правильное, ИМХО. И в целом, скрипт, должен бы быть построен так, чтобы если что-то не так с файлом в /tmp и т.д., то он бы закрывал порты по максимуму.

Лично я бы заморочился со скриптом для iptables, чтобы он сам определял домашняя сеть или нет (по содержимому /etc/network/interfaces, по ip-адресу на сетёвке), а порты в любом случае открвал только для ip-адресов домашней сети, которая не совпадает ни с билайном, ни с другими.

Относительно /bin/sh или /bin/bash решать вам, главное, что если вы пишите скрипты с «башизмами», то надо в начале скрипта писать, что это /bin/bash.

mky ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.