LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-15-2016, 03:06 AM   #1
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Rep: Reputation: 0
Multiple Input in bash


Hi,

I have a configuration file (mymy.conf) with following values:

ftp.enabled: true,
http.enabled: false,
rdp.enabled: false,
smb.enabled: true

and so on ...

I want to write a script where the above values would be set to "true" or "false" one by one.

For example: Filename:

Do you want to enable FTP? [Y/N] : y
Do you want to enable HTTP? [Y/N] : y
Do you want to enable RDP? [Y/N] : n
Do you want to enable SMB? [Y/N] :y
... so on till the end

I tried to used following code using multiple case but there is an issue:
Code:
#Enable/Disable PORTS [Ports]
				
				#===>FTP
                                read -p "Do you want to enable FTP Port? [y/N]" responseFTP
                                case "$responseFTP" in
                                        y|Y )
                                                #Enable
                                                sudo sed -i 's/\("ftp.enabled":\).*/\1 'true',/' mymy.conf ;;
                                        n|N )
                                                sudo sed -i 's/\("ftp.enabled":\).*/\1 'false',/' mymy.conf ;;
                                        * )     echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
                                esac;;
				 #===>HTTP
                                read -p "Do you want to enable HTTP Port? [y/N]" responseHTTP
                                case "$responseHTTP" in
                                        y|Y )
                                                #Enable
                                                sudo sed -i 's/\("http.enabled":\).*/\1 'true',/' mymy.conf ;;
                                        n|N )
                                                sudo sed -i 's/\("http.enabled":\).*/\1 'false',/' mymy.conf ;;
                                        * )     echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
                                esac;;
Is there any easier way?

Thanks
 
Old 12-15-2016, 03:47 AM   #2
TenTenths
Senior Member
 
Registered: Aug 2011
Location: Dublin
Distribution: Centos 5 / 6 / 7
Posts: 3,484

Rep: Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556
Quote:
Originally Posted by TashiDuks View Post
Is there any easier way?
Yes.

Use looping.

Code:
for OPTION in ftp http rdp smb ; do
  read -p "Do you want to enable ${OPTION} Port? [y/N]" RESPONSE
  case "${RESPONSE}" in
    y|Y )
      #Enable
      sudo sed -i 's/\("${OPTION}.enabled":\).*/\1 'true',/' mymy.conf ;;
    n|N )
      sudo sed -i 's/\("${OPTION}.enabled":\).*/\1 'false',/' mymy.conf ;;
    * )     echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
  esac;;
done
 
Old 12-15-2016, 05:24 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,041

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
you can also try to read the available options:
Code:
for OPTION in $(awk -F. '{print $1}' mymy.conf);
do
    ...
done

Last edited by pan64; 12-15-2016 at 05:25 AM.
 
Old 12-15-2016, 08:41 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
I would also force case on your test variable so you do not have to worry how the user inputs the information:
Code:
read -p "Do you want to enable ${OPTION} Port? [y/N]" RESPONSE
  case "${RESPONSE^}" in
    Y)...
    N)...
Also, TenTenths' example is fine but you will need to rework the quotes for the variables to work in the sed.

As usual, you only present a snippet of this imaginary conf file you keep using as an example, so I believe the seds can probably be made a lot simpler but would be unable to assist unless we get a better idea
of the original file.
 
Old 12-15-2016, 08:44 AM   #5
TenTenths
Senior Member
 
Registered: Aug 2011
Location: Dublin
Distribution: Centos 5 / 6 / 7
Posts: 3,484

Rep: Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556Reputation: 1556
Quote:
Originally Posted by grail View Post
Also, TenTenths' example is fine but you will need to rework the quotes for the variables to work in the sed.
Yeah, to be honest I dashed it out before my first coffee, so caveat emptor, YMMV, etc.
 
Old 12-15-2016, 10:23 PM   #6
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by TenTenths View Post
Yes.

Use looping.

Code:
for OPTION in ftp http rdp smb ; do
  read -p "Do you want to enable ${OPTION} Port? [y/N]" RESPONSE
  case "${RESPONSE}" in
    y|Y )
      #Enable
      sudo sed -i 's/\("${OPTION}.enabled":\).*/\1 'true',/' mymy.conf ;;
    n|N )
      sudo sed -i 's/\("${OPTION}.enabled":\).*/\1 'false',/' mymy.conf ;;
    * )     echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
  esac;;
done
Hi,

Thanks for the solution. Well I have used following line of codes using your example but i get error: (syntax check done in https://www.shellcheck.net/ )
Code:
 for PORTOPTN in ftp http rdp smb ; do
     read -p "Do you want to enable ${PORTOPTN} port? [y/N]" responsePORTS
           case "${responsePORTS}" in
               y|Y )
                    sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'true',/' mymy.conf ;;
               n|N )
                    sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'false',/' mymy.conf ;;
                *)    echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
            esac;;
  done
Error:
Code:
$ shellcheck myscript
 
Line 1:
 for PORTOPTN in ftp http rdp smb ; do
 ^-- SC1073: Couldn't parse this for loop.
                                    ^-- SC1061: Couldn't find 'done' for this 'do'.
 
Line 10:
                                        esac;;
                                            ^-- SC1062: Expected 'done' matching previously mentioned 'do'.
                                              ^-- SC1072: Unexpected . Fix any mentioned problems and try again.

$
Why it says "cannot find DONE for DO"?
 
Old 12-15-2016, 10:34 PM   #7
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
Remove ;; after esac.
 
Old 12-15-2016, 10:40 PM   #8
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by grail View Post
I would also force case on your test variable so you do not have to worry how the user inputs the information:
Code:
read -p "Do you want to enable ${OPTION} Port? [y/N]" RESPONSE
  case "${RESPONSE^}" in
    Y)...
    N)...
Also, TenTenths' example is fine but you will need to rework the quotes for the variables to work in the sed.

As usual, you only present a snippet of this imaginary conf file you keep using as an example, so I believe the seds can probably be made a lot simpler but would be unable to assist unless we get a better idea
of the original file.
Hi,
Thanks for the concern and I do understand what you trying to say, but I am sharing only the part of configuration file which I am working on it to make it more clear about the issue which I am facing.

Regards
 
Old 12-15-2016, 10:44 PM   #9
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Original Poster
Rep: Reputation: 0
Question

Quote:
Originally Posted by astrogeek View Post
Remove ;; after esac.
Now I am getting this error:
Code:
$ shellcheck myscript
 
Line 2:
                                  read -p "Do you want to enable ${PORTOPTN} port? [y/N]" responsePORTS
                                  ^-- SC2162: read without -r will mangle backslashes.
 
Line 6:
                                                        sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'true',/' mymy.conf ;;
                                                                                                        ^-- SC2026: This word is outside of quotes. Did you intend to 'nest '"'single quotes'"' instead'? 
 
Line 8:
                                                        sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'false',/' mymy.conf ;;
                                                                                                        ^-- SC2026: This word is outside of quotes. Did you intend to 'nest '"'single quotes'"' instead'? 

$
 
Old 12-15-2016, 10:56 PM   #10
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
Quote:
Originally Posted by TashiDuks View Post
Now I am getting this error:
Code:
...
read -p "Do you want to enable ${PORTOPTN} port? [y/N]" responsePORTS
   ...^-- SC2162: read without -r will mangle backslashes.
sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'true',/' mymy.conf ;;
   ...^-- SC2026: This word is outside of quotes. Did you intend to 'nest '"'single quotes'"' instead'? 
sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'false',/' mymy.conf ;;
   ...^-- SC2026: This word is outside of quotes. Did you intend to 'nest '"'single quotes'"' instead'?
I am not familiar with shellcheck, but those are not actual errors, they are advisory warnings I think.

The first reminds you what read without -r will do - see man bash for that. Doesn't mean it is wrong.

The other two are telling you that true and false appear outside quotes, which may or may not be wrong. In your case I think it is wrong, based on your mymy.conf snippet format.
 
Old 12-16-2016, 02:44 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
I would also question why the true / false are not included inside the sed start and end quotes?
Code:
sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'true',/' mymy.conf ;;

sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 true,/' mymy.conf ;;
One reason you might be getting an error is due to the fact that being outside the call to sed now means the shell is handling the calls to true / false which are commands the shell will execute.
 
Old 12-18-2016, 06:38 AM   #12
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by astrogeek View Post
I am not familiar with shellcheck, but those are not actual errors, they are advisory warnings I think.

The first reminds you what read without -r will do - see man bash for that. Doesn't mean it is wrong.

The other two are telling you that true and false appear outside quotes, which may or may not be wrong. In your case I think it is wrong, based on your mymy.conf snippet format.
I finally came up with following lines of code where execution is fine without any errors but it does not change any values in my config file.
Code:
#Variable
                                var1=true
                                var0=false
                                #Enable/Disable PORTS [Ports]
                                for PORTOPTN in ftp http smb mysql ssh rdp sip snmp ntp tftp telnet mssql vnc rdp;
                                  do
                                    read -p "Do you want to enable ${PORTOPTN^^} Port? [y/N]" responsePORTS
                                     case "${responsePORTS}" in
                                        y|Y )
                                             sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 "$var1",/' mymy.conf ;;
                                        n|N )
                                             sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 "$var0",/' mymy.conf ;;
                                        * )  echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m " ;;
                                     esac
                                done
                                ;;
 
Old 12-18-2016, 06:40 AM   #13
TashiDuks
Member
 
Registered: Sep 2010
Posts: 54

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by grail View Post
I would also question why the true / false are not included inside the sed start and end quotes?
Code:
sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 'true',/' mymy.conf ;;

sudo sed -i 's/\("${PORTOPTN}.enabled":\).*/\1 true,/' mymy.conf ;;
One reason you might be getting an error is due to the fact that being outside the call to sed now means the shell is handling the calls to true / false which are commands the shell will execute.
Thanks. Is there any other option or to rephrase my line?
 
Old 12-18-2016, 08:10 AM   #14
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Well I would make a search for the port option and then use s/// to change just the true or false.
Something like:
Code:
#Enable/Disable PORTS [Ports]
for PORTOPTN in ftp http smb mysql ssh rdp sip snmp ntp tftp telnet mssql vnc rdp;
do
  read -p "Do you want to enable ${PORTOPTN^^} Port? [y/N]" responsePORTS
  case "${responsePORTS^}" in
    Y ) opt='true';;
    N ) opt='false';;
    * )  echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m "
         break;;
  esac
  sudo sed -i "/$PORTOPTN/s/:.*/: $opt/" mymy.conf
done
Edit: Fixed variable as per pan64's catch

Last edited by grail; 12-18-2016 at 12:36 PM. Reason: Teach me to copy and paste ;)
 
Old 12-18-2016, 08:49 AM   #15
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
The main problem is that the shell does not substitute $var in a 'string'
Split into two strings so it becomes a concatenation of 'part1' "$var" 'part2'!
The shell then does the substution and removes all the quotes, so sed sees one string.
Code:
for PORTOPTN in ftp http rdp smb
do
    read -p "Do you want to enable ${PORTOPTN} port? [y/N]" responsePORTS
    case "$responsePORTS" in
    y|Y )
        sudo sed -i 's/^ *\('"$PORTOPTN"'\.enabled: *\)[^,]*/\1true/' mymy.conf
    ;;
    n|N )
        sudo sed -i 's/^ *\('"$PORTOPTN"'\.enabled: *\)[^,]*/\1false/' mymy.conf
    ;;
    * )
        echo -e "\033[38;5;1mWrong option used. Operation terminated!!!\033[0m "
    ;;
    esac
done
Comment on the previous post: the break ends the loop, a continue would continue the loop.

Last edited by MadeInGermany; 12-18-2016 at 08:56 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] stty: standard input: Input/output error [bash] DoME69 Programming 7 05-22-2015 12:14 AM
Bash - Replace multiple lines in file based on user input from php? nicedreams Programming 9 04-22-2015 09:11 AM
Linux Bash while loop reading multiple field text input and running remote commands bong_water Programming 2 02-11-2015 10:28 PM
bash script to read multiple user input prasunjit Programming 1 03-31-2013 02:09 PM
read multiple input with bash zulsolar Programming 10 05-09-2010 02:22 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:02 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration