1

Хочу написать скрипт который при запуске будет просить пользователя ввести значение для переменной и только после ввода будет продолжать работу, при этом запретить использование пробела и спец символов (всех окромя дефиса и подчеркивания, в том числе точки, запятой и т.д.), а в случае если пользователь все же ввел запрещенный символ заменять его на дефис или подчеркивание и при этом вывести сообщение что был использован запрещенный символ и содержимое переменной было приведено к виду и вывести то что получилось после замены, если пользователь согласен с таким значением - жмет Y, если нет - жмет N и возвращается к вводу значения заново.

2

на лабораторную похоже

echo "Please, enter value .. "

read VALUE

if [ проверка ввода ]..

"Фирма Майкрософт не собирается поддерживать протокол TCP/IP в своих OS" 1993 (c) Билл Гейтс
"Мы изобрели новый протокол передачи данных, мы назвали его TCP/IP" 1995 (c) Билл Гейтс

3

sotariz пишет:

просить пользователя ввести значение для переменной

help read
man bash
sotariz пишет:

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

тоже read, только по одному символу (опция -c), и без эха. Эхо делайте сами

help echo
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

4

moshell пишет:

на лабораторную похоже

похоже)) но это для личного удовлетворения и снижения затрат времени для создания сертификатов openvpn ab

moshell пишет:

read VALUE

сама VALUE это и есть переменная в которую будет записываться ввод или что это?

moshell пишет:

if [ проверка ввода ]

вот тут загвоздочка - пока еще не сталкивался с пробегом по тексту в поиске нужного символа

5

drBatty, за отправление в ман спасибо... правда они мне тяжко даются, быстрее понимаю с примерами и в обсуждении

6

sotariz пишет:

сама VALUE это и есть переменная в которую будет записываться ввод или что это?

оно и есть
Ладно, раз НЕ лаба, то напишу сейчас что-то похожее. Через 10 минут, если не забанят ab

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

7

$ ./sotarizm.bash 
qwer__aa--
qwer??aa??
$ cat sotarizm.bash 
#!/bin/bash

read VALUE

LEN_VALUE=${#VALUE}

for (( J = 0; J < LEN_VALUE; J++)); do
    C="${VALUE:$J:1}"
    if [ "$C" == "-" ] || [ "$C" == "_" ]; then
        C="?"
    fi
    echo -n "$C"
done
echo
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

8

банить доктора - не спортивно.
банить доктора - кощунство!

да, вспыльчив.
да, клоуничает.
да, самоуверен.

всем великим людям сложно жить в этом мире  bt

"Фирма Майкрософт не собирается поддерживать протокол TCP/IP в своих OS" 1993 (c) Билл Гейтс
"Мы изобрели новый протокол передачи данных, мы назвали его TCP/IP" 1995 (c) Билл Гейтс

9 (11.10.2013 13:35:21 отредактировано -=Serj=-)

drBatty,

sotariz пишет:

запрещенный символ заменять на дефис

#!/usr/bin/env python
#_*_ coding: utf-8 _*_

import re

st = raw_input("Enter string: ")
print(re.sub(r'[,./?`~!@#$%^&*()+=|\"\'\\]', '-', st))
$ ./input.py 
Enter string: xcv?xcvx.rtert'ert\e567
xcv-xcvx-rtert-ert-e567
Да, у меня Ubuntu.
Нет, не глючит.

10 (11.10.2013 13:30:29 отредактировано moshell)

sotariz, Вы бы для начала изучили код перед запуском,
а то мало ли..

давно известный мем в рунете о том, как "кракозябры" сотворяют  rm -rf /
ag

"Фирма Майкрософт не собирается поддерживать протокол TCP/IP в своих OS" 1993 (c) Билл Гейтс
"Мы изобрели новый протокол передачи данных, мы назвали его TCP/IP" 1995 (c) Билл Гейтс

11 (11.10.2013 14:41:04 отредактировано bormant)

drBatty пишет:
for (( J = 0; J < LEN_VALUE; J++)); do
    C="${VALUE:$J:1}"
    if [ "$C" == "-" ] || [ "$C" == "_" ]; then
        C="?"
    fi
    echo -n "$C"
done

Проще. Сначала man tr, потом что-то вроде:

QVALUE=$(echo $VALUE | tr "[:cntrl:][:space:],./?`~!@#$%^&*()+=|\"\'\\" "_")
if [ x"$QVALUE" != x"$VALUE" ]; then # была замена, надо спросить пользователя...
...
fi

12

bormant, цель моего примера: научить работать с символами в bash. По одному.

И да, ваш код тоже можно упростить до

${VALUE//[-_]/?}
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

13

-=Serj=- пишет:

#!/usr/bin/env python

зачем питон, если есть bash? Почему например не perl?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

14

drBatty пишет:

зачем питон, если есть bash? Почему например не perl?

Пишу на том, что более-менее знаю. И.. зачем bash, если есть python? ab

Да, у меня Ubuntu.
Нет, не глючит.

15 (11.10.2013 14:46:47 отредактировано bormant)

drBatty пишет:

тоже можно упростить до

можно, главное помнить, что ${parameter//a/b} -- bash-изм и не применять там, где может быть не bash (например, установочные сценарий пакета Slackware (install/doinst.sh сотоварищи) ;-) )

drBatty пишет:

научить работать с символами в bash. По одному.

А вот именно такое, работа с символами в bash, чаще всего требует чего-то более простого/универсального (не всегда, допускаю случаи, когда без этого ну никак не обойтись).

16

bormant пишет:

bash-изм

началось. А $() не башизм, не?

bormant пишет:

А вот именно такое, работа с символами в bash, чаще всего требует чего-то более простого/универсального (не всегда, допускаю случаи, когда без этого ну никак не обойтись).

ИМХО более простое/универсальное -- команда y из perl&sed.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

17

bormant, да, кстати. Про совместимость. Эта ваша tr (как и perl по дефолту) не умеет работать с utf-8.

$ echo "☢-☢-☢-☢" | tr '-☢' '+☣'
tr: неверный ключ — «�»
По команде «tr --help» можно получить дополнительную информацию.
$ echo "☢-☢-☢-☢" | sed 'y/-☢/+☣/'
☣+☣+☣+☣

т.е. про русский язык можно смело забыть...

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

18 (11.10.2013 15:17:32 отредактировано bormant)

drBatty пишет:

А $() не башизм, не?

Нет. http://www.opennet.ru/man.shtml?topic=s … 8+man#lbBI

Command Substitution
     Command substitution allows the output of a command to be substituted in place of the command name itself.  Command substitution occurs when the command is enclosed as follows:

           $(command)

     or (“backquoted” version):

           `command`


drBatty пишет:

Про совместимость. Эта ваша tr (как и perl по дефолту) не умеет работать с utf-8.

Угу. Не здорово. Вот только с точки зрения примера этого топика (замена на "-" или "_" символов "пробела и спец символов (всех окромя дефиса и подчеркивания, в том числе точки, запятой и т.д.)") это не имеет никакого значения (так устроена utf8). Верите?
Ах да, если к спецсимволам относится что-то не из ASCII, то tr действительно не подойдет.
И да, поскольку правильный вопрос должен завсегда содержать более половины ответа, целесообразнее определить, не что удалять, а что оставлять, заменяя всё остальное -- не останется возможности для разночтений.

19

bormant пишет:

Верите?

а у ТСа bash. Верите? Да, я тоже умею придираться к словам bx

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

20 (11.10.2013 20:08:23 отредактировано bormant)

drBatty, это была не придирка, а вопрос о том, нужно ли вдаваться в особенности utf8 в части невстречаемости кодов верхней половины ASCII в составе  2+ байтовых комбинаций символов в utf8.
А про bash/не-bash в исходном сообщении не было. Да и не в том дело, как правило аналогичные задачи уже имеют решение, не требующие посимвольного перебора строк (о чём выше уже говорил), а использование расширенных возможностей bash -- поминания о них. Впрочем, шебанг вполне можно считать таковым поминанием.

21

Спасибо всем за участие! Но ребята, почти весь этот спор не имеет смысла.... все что я хотел бы сделать так это проверку случайного нажатия shift при вводе чисел, более чем достаточно.
А вот в продолжение реализации сего чудо-действенного скрипта возник вопрос...
Как же правильно разложить все это в скрипте.
1. Спрашиваем значение переменной (имя ключа)
2. Проверяем ввод и при необходимости заменяем
3. Если замены не было выполняем генерацию
4. Если замена была выводим что вышло и спрашиваем пользователя продолжать или нет
5. Пользователь ответил ДА - выполняем пункт 3
6. Если пользователь ответил НЕТ - выполняем пункт 1

name()
{
        echo "имя?"
        read VALUE
        CLIENT_NAME=$(echo $VALUE | tr "[:cntrl:][:space:]/?~!@#$%^&*()+=|\"\'\`\\,." "-")
}
if [ "$VALUE" == "$CLIENT_NAME" ]
        then
                gen-key ()
                {
                        генерируем ключ и выполняем все что задумали
                }
        else
                echo "Ошибка"
                echo $CLIENT_NAME
                echo "Использовать это?(y/n)"
                read ANSWER
                if [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "y" ] || [ "$ANSWER" == "N" ] || [ "$ANSWER" == "n" ]
                        then
                                 if [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "y" ]
                                        then
                                                gen-key (использовал while do done, как правильно?)
                                        else
                                                name
                                fi
                        else
                                echo "Операция прервана!"
                fi
fi

Так не выполняется, точнее ничего не запрашивает. Если выполнять от обычного пользователя ругается что нет доступа (логично), а если от рута то просто спустя секунду я снова в консоли.

22

sotariz,

1. у вас синтаксически неверная функция внутри блока if/then/fi с именем gen-key

Кроме того, не советую писать имя функции через "минус" (-). Используйте подчерк, gen_key.

2. функция в bash НЕ выполняется в первый раз. Это её описание. Например:

#!/bin/bash
# не забываем в первой строке указывать ЯП, их много, и у них разный синтаксис!

пожарить_рыбу()
{
 кинуть рыбу на сковородку, и жарить 5 минут
 рыба готова
}

if мы_поймали_рыбу
then
  пожарить_рыбу
fi

в этом коде сначала выполняется функция(её мне лень писать) мы_поймали_рыбу, и если она удачно выполнилась, то выполняется функция пожарить_рыбу.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

23 (15.10.2013 12:55:51 отредактировано sotariz)

drBatty, про первую строку понятно, я просто передавал примерную структуру
суть уловил, буду пробовать дальше. Спасибо! ab

UPD
При проверке имени добавляется лишний символ замены в конец имени, от чего это?

./keys-creater.sh
Введи имя клиента:
test&key%ovpn
Была допущена ошибка ввода, имя преобразовано в:
test-key-ovpn-
Использовать это имя для генерации ключей?(y/n)
n
Введи имя клиента:
^C

24

sotariz, первая строка с интерпретатором вопервых мне нужна, ибо сложно понять, ЧТО вы тут написали, вот так с ходу. Во вторых вашей ОС. Ей тоже так проще. Не всегда bash === /bin/sh.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

25

drBatty пишет:

первая строка с интерпретатором

#!/bin/bash

drBatty пишет:

Во вторых вашей ОС

Debian 7

26 (15.10.2013 13:07:40 отредактировано sotariz)

В целом выглядит так... топорно, но главное результат ab

cat keys-creater.sh
#!/bin/bash
name()
{
        echo "Введи имя клиента:"
        read VALUE
        CLIENT_NAME=$(echo $VALUE | tr "[:cntrl:][:space:]/?~!@#$%^&*()+=|\"\'\`\\,." "-")
}

gen_key()
{
        echo "Начинается генерация ключей, дождитесь завершения..."
        cd /etc/openvpn/easy-rsa/2.0/
        source ./vars
        ./pkitool $CLIENT_NAME
        cp keys/"$CLIENT_NAME".* ../../keys/
        cd /etc/openvpn/ccd/
        touch $CLIENT_NAME
        echo "ifconfig-push 10.0.0.100 10.0.0.101" > $CLIENT_NAME
        cd /etc/openvpn/easy-rsa/2.0/
        mkdir -p /home/sotariz/vpn-keys/$CLIENT_NAME
        cp keys/"$CLIENT_NAME".* /home/sotariz/vpn-keys/$CLIENT_NAME/
        cp keys/ca.crt ../../keys/ta.key keys/dh2048.pem /home/sotariz/vpn-keys/$CLIENT_NAME

        echo "client" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "dev tun" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "remote xxx.xxx.xxx.xxx" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "resolv-retry infinite" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "nobind" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "persist-key" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "persist-tun" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "ca /etc/openvpn/ca.crt" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf  
        echo "cert /etc/openvpn/$CLIENT_NAME.crt" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "key /etc/openvpn/$CLIENT_NAME.key" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf 
        echo "comp-lzo" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "float" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf   
        echo "verb 3" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf  
        echo "script-security 2" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "tls-client" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "tls-auth /etc/openvpn/ta.key 1" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "auth MD5" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "cipher BF-CBC" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf
        echo "ns-cert-type server" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf

        sleep 5
        echo "...done!"
}

name

if [ "$VALUE" == "$CLIENT_NAME" ]
        then
                gen_key
        else
                echo "Была допущена ошибка ввода, имя преобразовано в:"
                echo $CLIENT_NAME
                echo "Использовать это имя для генерации ключей?(y/n)"
                read ANSWER
                if [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "y" ] || [ "$ANSWER" == "N" ] || [ "$ANSWER" == "n" ]
                        then
                                if [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "y" ]
                                        then
                                                gen_key
                                        else
                                                name
                                fi
                        else
                                echo "Ошибка ввода!"
                                echo "Операция прервана!"
                fi
fi

27

sotariz пишет:

Debian 7

там вроде по дефолту в некоторых случаях более простенький dash http://ru.wikipedia.org/wiki/Debian_Almquist_shell

sotariz пишет:

cp keys/"$CLIENT_NAME".* ../../keys/

тут не нужны кавычки ИМХО

sotariz пишет:

echo "client" >> /home/sotariz/vpn-keys/$CLIENT_NAME/"$CLIENT_NAME".conf

что-бы так не мучится, используйте встроенные документы http://www.bash-scripting.ru/abs/chunks/ch18.html

sotariz пишет:

но главное результат

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

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

28

Но вот все же как побороть вставку символа замены в конец?.. какого лешего он вообще туда попадает? 0_о

29 (15.10.2013 17:33:02 отредактировано bormant)

Вместо "echo $VALUE ..." нужно "echo -n $VALUE ..." поскольку echo добавляет в конец вывода перевод строки "\n"?

30

bormant, ну то что это реакция на Enter я предполагал, сейчас попробую с -n