LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 09-01-2019, 11:49 AM   #1
bmxakias
Member
 
Registered: Jan 2016
Posts: 164

Rep: Reputation: Disabled
Question How to compare the user input in bash scripting?


Hello

I have some folders like:


Code:
/backup/$DOMAIN/$DATE/database//inc/inc1
/backup/$DOMAIN/$DATE/database/inc/inc2
/backup/$DOMAIN/$DATE/database/inc/inc3
I am using this code:

Code:
     echo ""
     echo "Available increamental backups :"
     echo ""

PS3="

Please select the incremental backup point to restore [1, 2, 3 e.t.c]:"
# get the folders count
count=$(ls -1td $INCDIR/*/ | wc -l)

select domainbackupdate in $(ls -1td $INCDIR/*/ | awk -F/ '{print $(NF-1)}'); do
  # if input is a number and is less than or equal to count
  if (( $REPLY && $REPLY <= $count )) 2> /dev/null; then
    break
  else
    echo "Your input ${REPLY} is not available. Please select a number from the list:"
  fi
done

     echo "Please wait..." ;;
It does check in the folder $INCDIR/*/ all folders and shows them by order (newest first) like:

Code:
Available increamental backups :

1) inc3
2) inc2
3) inc1

Now what i would like to do is to get the input from the user selection (probably using the read command? ) and if the user select:

1 to run a command for folder inc1
2 to run a command for folder inc1 and then inc2
3 to run a command for inc1 and then inc2 and then inc3

But the problem is that what i will have in 1) or 2) or 3) may not be always the same...

So i must be able to read if it is just inc1 and run a simple cmmand or inc3 and run the 3 needed commands....

Is it possible to do that?

To work it must go from inc1 up to selected inc(x) that the user will select..

Thank you

Last edited by bmxakias; 09-01-2019 at 01:23 PM.
 
Old 09-01-2019, 11:58 AM   #2
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
yeah, you need to use a bash builtin called select.

We did some crafty things with that the other day
I'll find the link and edit this post for you


Edit
https://www.linuxquestions.org/quest...ds-4175659851/

you should get what you need from that

post what you come up if you get stuck

Last edited by Firerat; 09-01-2019 at 12:02 PM.
 
Old 09-01-2019, 12:09 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 18,927

Rep: Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851
Use $domainbackupdate. Its value will be one of the items in the output of the ls command i.e. inc1,inc2 or inc3 in your posted example. So the solution is easier then you think.

There are lots of string manipulation tools to separate the number from inc and then you can use a loop to go from inc1 to the selected inc(x).

https://bash.cyberciti.biz/guide/Select_loop

Last edited by michaelk; 09-01-2019 at 12:41 PM. Reason: corrected variables.
 
Old 09-01-2019, 12:29 PM   #4
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (Chicago area)
Distribution: CentOS, MacOS, [Open]SuSE, Raspian, Red Hat, Slackware, Solaris, Tru64
Posts: 1,478

Rep: Reputation: 154Reputation: 154
Quote:
Originally Posted by bmxakias View Post
Code:
Please select the incremental backup point to restore [1, 2, 3 e.t.c]:"
# get the folders count
count=$(ls -1td $INCDIR/*/ | wc -l)

select domainbackupdate in $(ls -1td $INCDIR/*/ | awk -F/ '{print $(NF-1)}'); do
  # if input is a number and is less than or equal to count
  if (( $REPLY && $REPLY <= $count )) 2> /dev/null; then
    break
  else
    echo "Your input ${REPLY} is not available. Please select a number from the list:"
  fi
done
You can use "select" but I've always found that to be an ugly way to go if there are a lot of options. I normally like to make an interface like that screen oriented and read everything that would be a possible option into an array and calculate indices that provide a window into the array and then display only as many as the user's terminal size can hold reserving space for prompting and reading the user's input, and reminders about the "previous screen" and "next screen" options. Takes a bit more effort to code but I think it's more user friendly. Depends on your end-user's needs. When I last used the method above, I was working with SQL developers who a.) sometimes had directories that often had hundreds datasets that they needed to select from for testing and b.) an aversion to organizing their data into logical subdirectories with smaller numbers of files in each. They appreciated the screen-oriented approach rather than having to scroll through a long list of options.

I'll hunt for a simple example of this approach and post it if anyone's interested in seeing it. (Right now I'm off to the hardware store to polish of couple of tasks in the Job Jar. :^) )
 
Old 09-01-2019, 01:03 PM   #5
bmxakias
Member
 
Registered: Jan 2016
Posts: 164

Original Poster
Rep: Reputation: Disabled
I think that all solutions are related on how to get the user input and act on that....but on my case i need the script to understand the input number of the folder name like inc3 and then then to run a command for inc1 and then for inc2 and then for inc3 and then stop.

Maybe my knowledge is limited on that but i can't see on the provided links that functionality ... Maybe i didn't explain it well ?

Thanks for your replies !

Last edited by bmxakias; 09-01-2019 at 01:04 PM.
 
Old 09-01-2019, 01:25 PM   #6
bmxakias
Member
 
Registered: Jan 2016
Posts: 164

Original Poster
Rep: Reputation: Disabled
To explain it a bit better...

If user select the folder inc1 that can have any number at the selection menu i would like to run this command:

Code:
touch /backup/$DOMAIN/$DATE/database/inc/inc1/file.txt
If user select for example the folder inc3 that can have any number at the selection menu i would like to run this:

Code:
touch /backup/$DOMAIN/$DATE/database/inc/inc1/file.txt
touch /backup/$DOMAIN/$DATE/database/inc/inc2/file.txt
touch /backup/$DOMAIN/$DATE/database/inc/inc3/file.txt
Thank you !
 
Old 09-01-2019, 01:52 PM   #7
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
in the link I posted we talked about how to decide what to do once the user had selected the option

so if user selects inc3
to recreate that you first restore inc1, then inc2 and finally inc3

if user selects inc2
to recreate that you first restore inc1 and finally inc2

if user selects inc1
restore inc1


ok

you built an array starting at 0
0=inc1
1=inc2
2=inc3

then with select presented it as

1) 2=inc3
2) 1=inc2
3) 0=inc1

Code:
Count of backups is 3

REPLY=1 ( 2=inc3 )
Count-REPLY = 2 .. 3 - 1 = 2 
for 0 1 2;do 
   restore incX
done


REPLY=2 ( 1=inc2 )
Count-REPLY = 1 .. 3 - 2 = 1
for 0 1;do
   restore incX
done

REPLY=3 ( 0-inc1 )
Count-REPLY = 0 .. 3 - 3 = 0
for 0;do
   restore inc
done
so, unchecked code

Code:
Dirs=## array comes from code I wrote in the other thread
# which needs check for gaps
# it is a lil dumb 

for ((i=0;i<$(($Count - $REPLY));i++));do
    restore "${Dirs[i]}"
done

does that make sense?
Note : /!\ things like that are out by 1 if they are wrong
 
Old 09-01-2019, 03:08 PM   #8
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Code:
#!/bin/bash
Dir="$1"

[[ $Dir == test ]] \
    && mkdir -p testing/inc{1..3} \
    && Dir="testing/inc"
# Edit1: I had Dir being set to testing all the time
# Doh! 
Dirs=()

for i in ${Dir}*;do
    [[ ${i} =~ ${Dir}[0-9]+ ]] && Dirs+=("${i}")
done

for (( i=$(( ${#Dirs[@]} - 1)) ; i >= 0; i-- ));do
    SelectDir+=("${Dirs[i]}")
done

select CHOICE in "${SelectDir[@]}";do
    [[ "$CHOICE" ]] && break
done

for ((i=0;i <= $((${#Dirs[@]} - $REPLY));i++));do
    echo restore "${Dirs[i]}"
done
but check what happens if you have more than 9 dirs!!

Last edited by Firerat; 09-01-2019 at 03:16 PM.
 
Old 09-01-2019, 03:31 PM   #9
michaelk
Moderator
 
Registered: Aug 2002
Posts: 18,927

Rep: Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851Reputation: 2851
If you choose inc3 the value of $domainbackupdate will equal inc3. Using a substring function you can assign a variable to equal 3 in this case.

From there you can create a loop from 1 to 3 to create the file.txt files in each incx directory without knowing the order of the select menu.
 
Old 09-01-2019, 04:16 PM   #10
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
yeah true


Code:
select CHOICE in "${Dirs[@]}";do
   [[ "$CHOICE" ]] && break
break
echo "$REPLY"
echo "$(( $REPLY - 1 ))"
echo "${Dirs[$(( $REPLY - 1 ))]}"
echo "${Dirs[$(( $REPLY - 1 ))]##*/}"
getnumber="${Dirs[$(( $REPLY - 1 ))]##*/}
getnumber="${getnumber//[^[:digit:]]/}"
echo $getnumber
if the array is in numerical order you just need to know which direction to walk

you can get the digit from the string and reconstruct, but you already have all that
bash will have globbed in numerical order

reconstructing negates the need for 000pad
but the order things are presented in will look messy
000pad and reconstruct needs more work to strip the leading 0s ( 08 != 8 )

gaps ( inc1 inc3 # inc2 is missing ) will break .. well both I guess
the reconstructed won't find inc2
with the array the restore will fail ( I assume inc3 depends on inc2)

This is where metadata needs to be put in the backups,
a first pass checks the dependencies and then restores once it confirms they are satisfied

which makes it even easier, since inc3 we check inc3/metadata and it says well I need inc2 first, inc2/metadata says well, I need inc1 first

so we only need to run restore on "${Dirs[$(( $REPLY - 1 ))]}"

does that make sense?
 
Old 09-02-2019, 04:44 AM   #11
bmxakias
Member
 
Registered: Jan 2016
Posts: 164

Original Poster
Rep: Reputation: Disabled
Thanks for your replies !!!!

The inc folders may be up to 46 ....

Can you please adjust your code for that so i can see the difference ?


Also if it is easier to do it by changing anything in the paths names, it's ok to do that...

For example if 1inc, 2inc or 1-inc, 2-inc is better for the script.....

Last edited by bmxakias; 09-02-2019 at 04:55 AM.
 
Old 09-02-2019, 05:29 AM   #12
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
you need to pad the 1 2 3 with leading zeroes 001 002 003 .. 999 1000 /!\ 1000 breaks it

you could use printf to pad
revisit the creation part
https://www.linuxquestions.org/quest...me-4175660121/


This is inspired by GazL's post

I added option to order Ascending/Descending

Code:
#!/bin/bash
Dir="${1%/}"

[[ $Dir == test ]] \
    && mkdir -p testing/inc{1..3} \
    && Dir="testing/inc"

Dirs=() # initial array ${#Dirs[@]} == 0
for i in ${Dir}*;do
    [[ ${i} =~ ${Dir}[0-9]+ ]] && Dirs+=("${i}")
done

Ascending(){
    choose "${Dirs[@]}"
return $?
}
Descending(){
    choose $(
       for (( i=$(( ${#Dirs[@]} - 1 )) ; i >= 0; i-- ));do
           printf "%s " "${Dirs[i]}"
       done
       )
return $?
}
choose(){
    select CHOICE in "${@}";do
        [[ "$CHOICE" ]] && break
    done
    restore "${CHOICE}"
return $? 
}
restore(){
# restore function
echo restoring "${1}/metadata"
}

select order in Ascending Descending;do
    [[ "$order" ]] && $order && break 
done
 
Old 09-02-2019, 09:45 AM   #13
bmxakias
Member
 
Registered: Jan 2016
Posts: 164

Original Poster
Rep: Reputation: Disabled
Can you please remove from your code the creation of the folders (as i do that from the backup script) and i already adjust it and now i have:

Code:
/backup/$DOMAIN/$DATE/database//inc/inc001
/backup/$DOMAIN/$DATE/database/inc/inc002
/backup/$DOMAIN/$DATE/database/inc/inc003

Also Ascending/Descending doesn't matter .... we may remove that also....

I just need to list folders and get the user input ...

With the above code i am getting the Ascending/Descending menu but i don't see anything listed to select and see if it works...

Thank you

Last edited by bmxakias; 09-02-2019 at 09:56 AM.
 
Old 09-02-2019, 09:50 AM   #14
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: FreeBSD/Slackware-14.2+/ArcoLinux
Posts: 9,079

Rep: Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903
N/M

Last edited by BW-userx; 09-02-2019 at 09:59 AM.
 
Old 09-02-2019, 10:01 AM   #15
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,994

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550


bless

I was just trying to inspire , not actually write it for you

look at them as working examples, not working scripts.


out of interest, how did you pad with 00?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Bash Scripting Help, can't get values to compare seanferd Linux - General 5 01-08-2014 07:05 PM
[SOLVED] Bash scripting problem: CSV list of filenames and actual files compare; Issue with plus symbol gn000we Linux - General 2 08-05-2013 06:57 PM
bash scripting... taking user input and adding it to a particular area of a file... dagummit Programming 7 01-13-2010 12:07 AM
User input into Bash scripts and checking validity of user input?? helptonewbie Programming 8 07-07-2008 06:40 PM
Bash scripting and user input Woodsman Slackware 13 11-02-2005 02:20 PM

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

All times are GMT -5. The time now is 08:18 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration