prompt and read a value as input for shell script - linux

I am trying to create a shell script where it should prompt and read the values as input and then update the same shell script with that value in a specific line and column.
Or if i can use another shell script to get the values and update original file.
i wanted to read and update below parameters values as input
USER=''user''
PASS=''password''
URL=''http://10.xxx.xxx.xxx:9206/MGR/status''
PORT1=''9204''
PORT2=''9206''
Full script
#!/bin/bash
USER=''user''
PASS=''password''
URL=''http://10.xxx.xxx.xxx:9206/MGR/status''
PORT1=''9204''
PORT2=''9206''
echo Metrics for $PORT1
echo =====================
maxthreads=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $4 }'`
echo Max Threads: $maxthreads
currentthreadcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $8 }'`
echo Current Threads: $currentthreadcount
busythreadcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{gsub("<br>", "");print $12}'`
echo Busy Threads: $busythreadcount
maxprocesstime=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $16 }'`
echo Max Processing Time: $maxprocesstime
processtime=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $20 }'`
echo Processing Time: $processtime
requestcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $24 }'`
echo Request Count: $requestcount
errorcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT1}.* | awk '{ print $27 }'`
echo Error Count: $errorcount
echo Metrics for $PORT2
echo =====================
maxthreads=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $4 }'`
echo Max Threads: $maxthreads
currentthreadcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $8 }'`
echo Current Threads: $currentthreadcount
busythreadcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{gsub("<br>", "");print $12}'`
echo Busy Threads: $busythreadcount
maxprocesstime=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $16 }'`
echo Max Processing Time: $maxprocesstime
processtime=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $20 }'`
echo Processing Time: $processtime
requestcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $24 }'`
echo Request Count: $requestcount
errorcount=`curl -s -u ${USER}:${PASS} ${URL} | grep -o ${PORT2}.* | awk '{ print $27 }'`
echo Error Count: $errorcount
My intension is not to edit the file and input values, instead read it as prompt and update the file in background.

Thanks Team. I did another method for achieving this using AWS secret manager. The code can read the data from secret manager. So our engineer can update the same in secret manager as a key value pair. Thank you all for the suggestion and help. I will further look into the option suggested to improve the code.

Related

How do I use to pass output from command as parameter to another (complex)?

I am trying to somewhat automate the certificate bundle update on the F5 devices.
There is not one command that can check for SSL bundle expiry and match it to the server SSL profile name. So I am trying to do it with greps (as its all I know =)
There are two commands:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}'
This will give an output of expired bundle names, one on each line, like this
Common/somebundle.crt
Common/someotherbundlename.crt
Common/whoknowswhatthisbundleisfor.crt
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain'
This command will get a list of all server-ssl profile names and its links to certs/bundles etc. I am them using | grep Common/somebundle.crt -B 1 to only give me info about a particular output from the command 1 output. So command 2 becomes:
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep Common/somebundle.crt -B 1
Then I have to manually repeat for each of the found bundles in command 1 output.
I am trying to somehow use command 1 and then either xargs (or whatever I can) to run the command 2, passing the output from 1 into the grep in 2
It does not have to be one-liner, I just dont know bash enough to write a script
I have created something that works, though not very clean looking =)
for i in $(tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}'); do echo -n "$i -> "; tmsh -c "cd /;list ltm profile server-ssl recursive" | grep -B20 $i >> /dev/null || echo "Not Found" && tmsh -c "cd /;list ltm profile server-ssl recursive" | grep -B20 $i |grep -i "ltm profile" | tail -n1 | awk -F "{" '{print $1}' ; done
It should be possible with bash while loop and read function. You can pipe your first command into while loop, reading line-by-line your output:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}' | while read bundle;do tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep "$bundle" -B 1 |...do whatever else is needed ;done
It also can be splitted into normal multiline script:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}' | while read bundle
do
echo "===== $bundle ===="
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep "$bundle" -B 1 |...do whatever else is needed
done

How to direct linux bash script output to one line per host

I'd like to change my script(s) so that the command output is separated by a comma and is all on one line per host. Any ideas on how I can achieve this:
1st Script:
#!/bin/bash
for i in `cat ~/hostnames.txt`
do
ssh -q $i 'bash -s' < server_info.sh
done
2nd Script (server_info.sh):
#!/bin/bash
echo -n "Name: "
uname -n
echo -n "CPUs: "
cat /proc/cpuinfo* | grep processor | wc -l
echo -n "Memory (kb): "
cat /proc/meminfo | grep MemTotal: | awk '{print $2}'
echo -n "Current Kernel: "
uname -a | awk '{print $3}'
echo -n "IP: "
hostname -i
echo -e
Changing your 1st script:
#!/bin/bash
for i in cat ~/hostnames.txt
do
ssh -q $i 'bash -s' < server_info.sh
done | awk -v RS= '{$1=$1}1'
Note: Your server_info.sh can be a lot more optimized.For example:
cat /proc/meminfo | grep MemTotal: | awk '{print $2}'
could be changed to:
awk '/MemTotal:/{print $2}' /proc/meminfo

Trying to get the output of time command

When I run the below command on the terminal it's working fine.
$ var=`(time mysqldump -v -u'user' -p'password' database > db-backup.sql 2>
/tmp/mysqldump-output) 2>&1 | grep real | awk '{print $2}' | cut -f1 -d"m"`
$ echo $var
0
But when I use same command in the bash script it's not working properly
Below is script:
$ cat db-backup.sh
#!/bin/bash
var=`(time mysqldump -v -u'user' -p'password' database > database-backup.sql 2> /tmp/mysqldump-output) 2>&1 | grep real | awk '{print $2}' | cut -f1 -d"m"`
echo $var
script output:
$ sh -x db-backup.sh
+ grep real
+ awk {print $2}
+ cut -f1 -dm
+ var=
+ echo
After running the script with bash it worked.
$ bash -x db-backup.sh
++ grep real
++ awk '{print $2}'
++ cut -f1 -dm
+ var=0
+ echo 0
0

Searching a specific file system in bash

I have a task which asks to write a script which displays all partitions formatted with a specific file system, given as parameter.
I have written the script but when i run it it displays '0'. What am i doing wrong?
This is my code:
#!/bin/bash
n=sudo parted -l | tail -n +8 | awk '{print $5}' | wc | awk '{print $2}'
m=sudo parted -l | tail -n +8 | awk '{print $5}'
q=sudo parted -l | tail -n +8
for i in $n; do
if [ "[ $m | sed -n ip ]" = "$1" ]; then
echo "$q | sed -n ip"
fi
done
Different approach from yours, but does it do what you need?
lsblk -f | awk '$0 ~ fs {print $NF}' fs=ext2

awk field separator using ":" and ignore spaces within ":"

I'm trying to automate the user creation(Bulk Users) in Linux. So, I've created a text file with all the needed parameters for user's creation.
The Text file contains the below content:
tom:tom1:588:0:test user1:/home/test:/bin/false
harry:harry1:589:0:test test2:/hom/test2:/bin/nologin
Trying to use awk command to print the column's in for loop and create the users with the information's from /tmp/user.txt
for userdetails in $(cat /tmp/user.txt)
do
user=`echo $userdetails | awk -v FS=: '{print $1}'`
passwd=`echo $userdetails | awk -v FS=: '{print $2}'`
uid=`echo $userdetails | awk -v FS=: '{print $3}'`
gid=`echo $userdetails | awk -v FS=: '{print $4}'`
comment=`echo $userdetails | awk -v FS=: '{print $5}'`
home_dir=`echo $userdetails | awk -v FS=: '{print $6}'`
user_shell=`echo $userdetails | awk -v FS=: '{print $7}'`
useradd -d "$home_dir" -c "$comment" -s "$user_shell" -u "$uid" -g "$gid" "$user"
echo "$passwd" | passwd "$user" --stdin;
done
Actual Output:
useradd: invalid home directory ''
passwd: Unknown user name 'tom'.
useradd: invalid home directory ''
passwd: Unknown user name 'user1'.
useradd: invalid home directory ''
passwd: Unknown user name 'harry'.
useradd: invalid home directory ''
passwd: Unknown user name 'test2'.
What I'm doing wrong ?
P.S : I am aware there is a command called newusers in Linux, but i need to check the same via script to create bulk users in Linux.
idk how you got started on that track but you're off-base. Just use a shell loop:
while IFS=':' read -r user passwd uid gid comment home_dir user_shell; do
useradd -d "$home_dir" -c "$comment" -s "$user_shell" -u "$uid" -g "$gid" "$user"
echo "$passwd" | passwd "$user" --stdin;
done < /tmp/user.txt
The above is just showing how to read the file contents into variables, it assumes you know what you're doing with the "useradd" and "passwd" lines.
I would use while for read a file by line so the entire line will be stored in the variable you choose( in my case: line) . Then you could echo variable and awk will do the rest of the work. I prefer $() than `` so I use both for now. For this much data you could create a loop into the while to make code sorter and better manageable.
cat /tmp/user.txt | while read line
do
user=`echo $line | awk -F ":" '{print $1}'`
passwd=$(echo $line | awk -F ":" '{print $2}')
uid=$(echo $line | awk -F ":" '{print $3}')
gid=$(echo $line | awk -F ":" '{print $4}')
comment=$(echo $line | awk -F ":" '{print $5}')
home_dir=$(echo $line | awk -F ":" '{print $6}')
user_shell=$(echo $line | awk -F ":" '{print $7}')
useradd -d "$home_dir" -c "$comment" -s "$user_shell" -u "$uid" -g "$gid" "$user"
echo "$passwd" | passwd "$user" --stdin;
done
If you are stuck with awk, you can use Awk Global substitution:
awk '{gsub(/:/,"-")} 1' your_file
This is also feasible using sed with the g flag ( Sed Global substitution ):
sed "s/:/-/g" your_file
In both casesn your edited lines would be printed to the screen.

Resources