How to create a script that is automated and sequential - linux

I'm struggling in trying to create a script in Linux (Terminal-Bash) which is automated and when run it will ask for a input and when that input is added it will create sequential files.
See below:
when script is run, it should show
Which country are you from?
I enter Brazil and wish to see:
Data entered: Brazil1, Brazil2, Brazil3.....Brazil 10
The script needs create a batch of 10 each time it is run i.e.
Which country are you from?
I enter Canada and wish to see:
Canada1, Canada2, Canada3.....Canada10
If brazil entered again: Brazil11, Brazil12....Brazil20 and Brazil21, Brazil22....Brazil30 etc
I do not want to hardcode the numbers, automation is required to create them each time.
**Testing:
**
I have created the script by:
Touch test.sh
I have tried to edit the script by:
vim test.sh
In vim I have made the below changes:
#!bin/bash
echo "Which country are you from"
value=country
value{1..10}
Save vim, when executing script I get this message:
test.sh: line 4: value1: command not found
Can someone please help with the script? I'm completely new to linux and trying to best understand how to create the simplest and most effective process.
Thanks in advance.

This script is pretty straightforward to implement. You need to use the read command to read user input in. You can use the while loop with -f to test which files already exist, and then finally the for loop to create those files
#!/bin/bash
echo Hello, what country are you from?
read user_country
n=1
while [ -f "$user_country$n" ]
do
let "n+=10"
done
for ((i=0; i<10; i++))
do
file_num=$((i + n))
touch "$user_country$file_num"
done

Related

Is there a way that i can download files from different URL's based on user input?

There are two releases
1. Dev available at https://example.com/foo/new-package.txt
2. GA available at https://example.com/bar/new-package.txt
I want the user to enter his choice of Dev or GA and based on that need to download the files, in the shell script is there a better way to do it?
There is a file which has environment variables that I'm sourcing inside another script.
env_var.sh
#!/bin/bash
echo "Enter your release"
export release='' #either Dev or GA
This file will be sourced from another script as
download.sh
#!/bin/bash
. ./env_var.sh #sourcing a environment var file
wget https://<Dev or GA URL>/new-package.txt
My main problem is how to set the wget URL based on the release set in env_var file.
Any help is appreciated.
Have you considered using read to get the user input?
read -p 'Selection: ' choice
You could then pass ${choice} to a function that has case statements for the urls:
get_url() {
case $1 in
'dev' ) wget https://example.com/foo/new-package.txt ;;
'ga' ) wget https://example.com/bar/new-package.txt ;;
\? ) echo "Invalid choice" ;;
esac
}
For more information on read, a good reference is TLDP's guide on user input.
Edit: To source a config file, run the command source ${PATH_TO_FILE}. You would then be able to pass the variable to the get_url() function for the same result.

bin/bash nested loop does not work

I currently working as a intern at a hosting firm. They asked me to write a bin/bash script to help automate a process to check the user's domain's and .pointers for them. And validate with a "whois" command if the domains/pointers are on our server's.
I'm new with bin/bash scripting but i was told i should check nested loops out. So to test my script out i made similar paths as they would look like on the server. /usr/local/directadmin/data/users/#USER#/domains.list and users/#USER#/domains/#DOMAIN NAME OF USER#.pointers
#part 1
for i in $(cat /home/MrC/Desktop/Users) #<the list of users i need to check)
do
if [ -f "/usr/local/directadmin/data/users/$i/domainlist.txt" ]
then
echo "/usr/local/directadmin/data/users/$i" >> /home/MrC/Desktop/output.tx$
cat "/usr/local/directadmin/data/users/$i/domainlist.txt" >> /home/carlos/Des$
fi
#part 2
for s in $(cat /home/mrC/Desktop/output.txt)
do
if [ -f "/usr/local/directadmin/data/users/$i/domains/$s.pointers" ]
then
echo "/usr/local/directadmin/data/users/$i" >> /home/MrC/Desktop/pointers.$
cat "usr/local/directadmin/data/users/$i/domains/$s.pointers" >> /home/MrC$
fi
done
done
So part 1 works this is the output.txt below
/usr/local/directadmin/data/users/testuser
lolla.nl
blaat2.nl
blaat3.nl
google2.nl
/usr/local/directadmin/data/users/testusers
blaat.nl
google.com
test.nl
pietje.nl
But i cant seem part two to work (no pointer file). my goal with part two of the script is to read the output (domainname) and put it #/$i/domains/$s.pointers.
I'm new on the forum i hope i asked my question in a proper fashion. if some one could give me hints/tips to which direction i should look that would be highly appreciated.
For
Do
if
then
for
do
COMMAND A
COMMAND B
COMMAND C
done
fi
done
while read -r i; do #stuff; done < /home/MrC/Desktop/Users (adjust IFS or specify the delimiter with the -d option to read).
– David C. Rankin

Send automatic input to a script called by another script in bash

I'm working on a bash script (my_script) in which I call many scripts, they all together automate a work flow.
But when I call one particular (ksh/bash) script (master_script) there are many inputs and checks taken (not arguments) in it.
It is slowing down the whole of the automation, as every time I have to super wise it and enter the values manually.
I have no option to modify or make a new script (work constraints)
Every time the questions are same. I am trying to take all the answers before executing master_script except one answer(whose value depends on the execution) and then feed it to the master_script at the correct time.
Is there a way we can pass the value to the master_script, during its execution from within my_script.? ./master_script<< EOF .. EOF will not help as I have to enter one answer myself.
The below is just an example and my creation, but depicts what exactly is my requirement.
Example code
my_script
#! /bin/bash
echo "Proceeding...."
#calling master_script
/master_script $arg1 $arg2
echo "Completed.."
echo "Executing other scripts"
/other_scripts"
Execution
$ sh ./my_script
Proceeding....
Started master_script..
Press Enter to Proceed MY_INPUT
Enter username to add (eg.user123) MY_UNAME
Enter preferred uid (eg.1234) MY_UID
Do you want to bla bla..(Y/n) MY_INPUT
Please select among the following
1.option1
2.Option2
Selection: MY_SELECTION
Please choose which extension to use
1.ext1
2.ext2
3.ext3
4.ext4
Do you want to bla bla 2..(Y/n) MY_INPUT
Ended master script
Completed..
Executing other scripts
Requirement
#! /bin/bash
echo "Proceeding...."
# get values for master script
read -p "Proceed(Y/n):" proceed1
read -p "Uname:" uname
read -p "Uid:" uid
read -p "bla bla (Y/n):" bla1
read -p "Selection(1/2):" selection1
read -p "bla bla 2(Y/n):" bla2
#calling master_script
./master_script $arg1 $arg2 {all_inputs}
#Silent Execution of master_script until choosing execution...
Please choose which extension to use
1. ext1
2. ext2
3. ext3
4. ext4
#Silent Execution of master_script after choosing ext and continue with other scripts
./other_scripts
echo "Completed.."
I've read about expect/send combination, but I'm unable to comprehend
how to use it. Any inputs will be greatly helpful
EDIT
I am also not sure about ./master_script<< EOF ... EOF as I have to enter one
answer in the middle of execution myself.
There is a solution using here documents and redirecting the input:
./master_script "$arg1" "$arg2" << ENDINPUT
$proceed1
$uname
$uid
$bla1
$selection1
ENDINPUT
Remark 1: the final ENDINPUT must start the line, don't indent! See Man bash
Remark 2: some scripts or programs check if the input comes from an actual terminal (calling isatty()), for instance when typing a password. It is still possible to automate the entries, but it is much more tricky.

Linux bash script - For loops issues

I'm working on a bash script that will add users in a batch process. This code goes as follows:
#!/bin/bash
# A script that creates users.
echo "This is a script to create new users on this system."
echo "How many users do you want to add?"
read am
echo " "
for i in {0..$am..1}
do
echo "Enter a username below:"
read usern
sudo useradd $usern
sudo passwd $usern
echo " "
echo "User $am '$usern' added."
done
In this case, I wanted to make 4 users. I went through and entered the username "callum3" and set the password as "1234" for ease of login. Once I input everything (correctly, may I add) the terminal window displays the following.
User 4 'callum3' added.
This shows that my for loop isn't actually working, when I can see nothing wrong with it. I have tried using a while loop with no luck there either.
Am I making a rookie mistake here or is there something deeper going on?
Although I suspected it, for a better understanding on what could be wrong with your script I pasted it in shellcheck.net. That the problem is in the line:
for i in {0..$am..1}
Bash doesn't support variables in brace range expansions. That is, you cannot use a variable in an expression like {..}.
Instead, use seq. With seq $var you get a sequence from 1 (default) to $var:
for i in $(seq "$am")
I feel like I'm missing something in that nobody has suggested an arithmetic for loop:
for ((i=0; i<am; i++)); do
…
done
This has the particular benefit in bash of being both readable and not requiring a subshell.
You can use:
for i in `seq 0 $((am-1))`
do
...
done
Sequence will start from 0 and end at $am-1

Shell reading and saveing to config.cfg file?

I am still very new to shell since I have been using it with linux recently, and I tried to mess with a game called garrysmod and make a little script that will ask for information to run the server, its IP, playerslots, etc. Now I somewhat got this working, but I want to be able to save and load this to a config file. I figure out how to get it load from the config, but I want to be able to edit it from the command prompt when it asks you if you would like to edit it.
This is what I have so far as an example:
setup.sh
source config.cfg
echo "Servers current name is $name"
echo
echo "What would you like the name to be?"
read $name
read "The new name is $name"\
config.cfg
name='ServerName'
address=127.0.0.1
port=27015
map='ttt_mapnamehere.bsp'
playercap=32
Now it works after you change it, but I don't know how to get it to save to the .cfg file. The reason of this is because several .sh files will run in order as you go through the steps, and at the end the file one will pull data from the config file being the IP, port, map name, player count, etc. If someone can show me how to do this (examples as Im a visual learner) that would be great!
Simply write it back:
...
printf "name='%s'\naddress='%s'\nport=%s\nmap='%s'\nplayercap=%s\n" \
"$name" "$address" "$port" "$map" "$playercap" > config.cfg

Resources