my script takes in a site name from the user.
./run_script <site>
./run_script cambridge
Its then allows the user to checkout, edit, and commit changes to the file, via the script.
However, some sites have two to six files.
So the script lists them as follows
You have more than one Cambridge file.
Please pick from the following:
cambridge1
cambridge2
cambridge3
user enters the word cambridge[1-3]
However, I'd like to assign a value to each variable, i.e, as follows.
Please choose the option you want:
1). cambridge1
2). cambridge2
3). cambridge3
user enters 1, 2, or 3, and it picks up the file.
The current code I have is :
echo $(tput setaf 5)
echo "Please choose from the following: "
echo -n $(tput sgr0)
find path/to/file/. -name *"$site"* | awk -F "/" '{print $5}' | awk -F "SITE." '{print $2}'
echo $(tput setaf 3)
read -r input_variable
echo "You entered: $input_variable"
echo $(tput sgr0)
Here's a fun way:
# save the paths and names of the options for later
paths=`find path/to/file/. -name "*$site*"`
names=`echo "$paths" | awk -F "/" '{print $5}' | awk -F "SITE." '{print $2}'`
# number the choices
n=`echo "$names" | wc -l`
[ "$n" -gt 0 ] || echo "no matches" && exit 1
choices=`paste <(seq 1 $n) <(echo "$names") | sed 's/\t/). /'`
echo "Please choose from the following: "
echo "$choices"
read -r iv
echo "You entered: $iv"
# make sure they entered a valid choice
if [ ! "$iv" -gt 0 ] || [ ! "$iv" -le "$n" ]; then
echo "invalid choice"
exit 1
fi
# name and path of the user's choice:
name_chosen=`echo "$names" | tail -n+$iv | head -n1`
path_chosen`echo "$paths" | tail -n+$iv | head -n1`
Related
I trying to make script that shows volume level of active volume sink. Here is code
#!/bin/bash
active_sink=$(pacmd list-sinks |awk '/* index:/{print $3}')
muted=$(pactl list sinks | perl -000ne 'if(/#${active_sink}/){/(Mute:.*)/; print "$1\n"}' | cut -f2 -d':' | cut -f2 -d' ')
vol=$(pactl list sinks | perl -000ne 'if(/#${active_sink}/){/(Volume:.*)/; print "$1\n"}' | cut -f1 -d'%' | tail -c 3
)
if [[ $muted = "no" ]]; then
if [[ $vol -ge 65 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-high.svg
echo "$vol%"
elif [[ $vol -ge 40 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-medium.svg
echo "$vol%"
elif
[[ $vol -ge 0 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-low.svg
echo "$vol%"
fi
else
echo ~/.config/tint2/executors/icons/audio-volume-muted.svg
echo "muted"
fi
I can't get this script to work, always get "muted".
I finally makes this thing to work, thanks #markp-fuso.
The problem was with perl and ${active_sink}.
Final code that work with corrected muted and vol
#!/bin/bash
active_sink=$(pacmd list-sinks | awk '/* index:/{print $3}')
muted=$(pactl list sinks | grep -A14 -P "(\#|№)$active_sink" | awk '/Mute:/{print $2}')
vol=$(pactl list sinks | grep -A14 -P "(\#|№)$active_sink" | awk '/Volume: front-left:/{print $5}' | cut -f1 -d'%')
if [[ $muted = "no" ]]; then
if [[ $vol -ge 65 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-high.svg
echo "$vol%"
elif [[ $vol -ge 40 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-medium.svg
echo "$vol%"
elif
[[ $vol -ge 0 ]]; then
echo ~/.config/tint2/executors/icons/audio-volume-low.svg
echo "$vol%"
fi
else
echo ~/.config/tint2/executors/icons/audio-volume-muted.svg
echo "muted"
fi
I am trying to output which accounts have been successfully created from a text file and which haven't. I would also like to output the number of successfully created accounts. I currently the get the following error: grep: 3: No such file or directory. The script and text file and saved in the same folder. I have use the following commands in my script.
file=users.txt
verify =grep "verify" $file |cut -f2 -d:`
cat /etc/passwd | grep $verify
echo -e "\nYou have Currently"
cat /etc/passwd | grep $verify |wc -l;
echo "users added from your Text File"
Edit:
#!/bin/bash
ROOT_UID=0 #The root user has a UID of 0
if [ "$UID" -ne "$ROOT_UID" ]; then
echo "**** You must be the root user to run this script!****"
exit
fi
clear
echo
echo "######################################################"
echo "##### Batch script to automate creation of users #####"
echo -e "######################################################\n"
while true;
do
file=notvalid
while [ $file == "notvalid" ]
do
#echo "repeat $repeat"
#echo -e "\n"
echo -n "Please enter import filename:"
read filename
echo -e "\r"
exists=0
if [ -e $filename ]; then
file=valid
while IFS=":" read firstname lastname userid password group
do
egrep -i "^$userid:" /etc/passwd &>/dev/null
if [ $? -eq 0 ]; then
exists=$((exists+1))
#echo -e "${firstname} ${lastname} already exists on the system"
#grep ${userid} /etc/passwd
aname=$( getent passwd "$userid" | cut -d: -f3)
echo "Account Exists: $aname"
euserid=$( getent passwd "$userid" | cut -d: -f1)
echo "User ID: $userid"
homedir=$( getent passwd "$userid" | cut -d: -f6)
echo "Home Directory: $homedir"
usershell=$( getent passwd "$userid" | cut -d: -f7)
echo "User Shell: $usershell"
g=$( id -Gn "$userid")
echo "Groups: $g"
echo -e "\r"
else
egrep -i "^$group:" /etc/group &>/dev/null
if [ $? -eq 1 ]; then
/usr/sbin/addgroup ${group} &>/dev/null
fi
useradd -d /home/"${userid}" -m -s /bin/bash -c \
"${firstname}${lastname}" -g "${group}" "${userid}"
echo "Creating Account: ${firstname} ${lastname}"
nuserid=$( getent passwd "$userid" | cut -d: -f1)
echo "Creating User ID: ${nuserid}"
{ echo ${password}; echo ${password}; } | sudo passwd ${userid} > /dev/null 2>&1
echo "Creating Password: ${password}"
echo "Creating Home Directory: /home/${userid}"
echo "Creating User Shell: /bin/bash"
echo -e "Assigning Group: ${group}\n"
fi
done < $filename
else
echo -e "##### CANNOT FIND OR LOCATE FILE #####"
fi
verify=`grep "verify" /home/pi/$filename | cut -f3 -d:`
echo "$verify"
count=0
for id in $verify
do grep -wo ^$id /etc/passwd && count=$((count+1))
done
echo $count users added from your text file
echo these are not added:
for id in $verify
do grep -wq ^$id /etc/passwd || echo $id
done
while true
do
echo -n "Create additional accounts [y/n]: "
read opt
if [[ $opt == "n" || $opt == "y" ]];then
break
else
echo "Invalid Input"
fi
done
if [ $opt = "n" ]; then
clear
break
else
clear
fi
done
You were almost there.
The main issue with your approach is that you try to search for multiple accounts at once with grep. The variable verify has multiple userids so you need to process it one by one.
file=users.txt
verify=`grep "verify" $file | cut -f2 -d:`
count=0
for id in $verify
do grep -wo ^$id /etc/passwd && count=$((count+1))
done
echo $count users added from your text file
echo these are not added:
for id in $verify
do grep -wq ^$id /etc/passwd || echo $id
done
The for loop will take each element in your verify variable into id and search with grep (-w matches only whole words, not fragments, ^ matches the beginning of line and -o outputs only the matching word not the whole line).
We count the number of matches in the count variable. Alternative approach to run the for loop twice and pipe the second one to wc -l as you did.
&& operator means it will increase count if the previous command found a match (the return code of grep was 0).
The next loop will not print matching ids (-q), and will echo id if grep did not found a match (the return code was not 0). This is achieved with the || operator.
One last note on iteration of a list: if the members can contain spaces (unlike userids), you should use ${verify[#]} (this is a bash-ism) instead of $verify .
And forget this: cat /etc/passwd | grep pattern, use grep pattern /etc/passwd instead.
enter image description hereI was trying to see how a shell scripts work and how to run them, so I toke some sample code from a book I picked up from the library called "Wicked Cool Shell Scripts"
I re wrote the code verbatim, but I'm getting an error from Linux, which I compiled the code on saying:
'd.sh: line 3: syntax error near unexpected token `{
'd.sh: line 3:`gmk() {
Before this I had the curly bracket on the newline but I was still getting :
'd.sh: line 3: syntax error near unexpected token
'd.sh: line 3:`gmk()
#!/bin/sh
#format directory- outputs a formatted directory listing
gmk()
{
#Give input in Kb, output converted to Kb, Mb, or Gb for best output format
if [$1 -ge 1000000]; then
echo "$(scriptbc -p 2 $1/1000000)Gb"
elif [$1 - ge 1000]; then
echo "$$(scriptbc -p 2 $1/1000)Mb"
else
echo "${1}Kb"
fi
}
if [$# -gt 1] ; then
echo "Usage: $0 [dirname]" >&2; exit 1
elif [$# -eq 1] ; then
cd "$#"
fi
for file in *
do
if [-d "$file"] ; then
size = $(ls "$file"|wc -l|sed 's/[^[:digit:]]//g')
elif [$size -eq 1] ; then
echo "$file ($size entry)|"
else
echo "$file ($size entries)|"
fi
else
size ="$(ls -sk "$file" | awk '{print $1}')"
echo "$file ($(gmk $size))|"
fi
done | \
sed 's/ /^^^/g' |\
xargs -n 2 |\
sed 's/\^\^\^/ /g' | \
awk -F\| '{ printf "%39s %-39s\n", $1, $2}'
exit 0
if [$#-gt 1]; then
echo "Usage :$0 [dirname]" >&2; exit 1
elif [$# -eq 1]; then
cd "$#"
fi
for file in *
do
if [ -d "$file" ] ; then
size =$(ls "$file" | wc -l | sed 's/[^[:digit:]]//g')
if [ $size -eq 1 ] ; then
echo "$file ($size entry)|"
else
echo "$file ($size entries)|"
fi
else
size ="$(ls -sk "$file" | awk '{print $1}')"
echo "$file ($(convert $size))|"
fi
done | \
sed 's/ /^^^/g' | \
xargs -n 2 | \
sed 's/\^\^\^/ /g' | \
awk -F\| '{ printf "%-39s %-39s\n", $1, $2 }'
exit 0
sh is very sensitive to spaces. In particular assignment (no spaces around =) and testing (must have spaces inside the [ ]).
This version runs, although fails on my machine due to the lack of scriptbc.
You put an elsif in a spot where it was supposed to be if.
Be careful of column alignment between starts and ends. If you mismatch them it will easily lead you astray in thinking about how this works.
Also, adding a set -x near the top of a script is a very good way of debugging what it is doing - it will cause the interpreter to output each line it is about to run before it does.
#!/bin/sh
#format directory- outputs a formatted directory listing
gmk()
{
#Give input in Kb, output converted to Kb, Mb, or Gb for best output format
if [ $1 -ge 1000000 ]; then
echo "$(scriptbc -p 2 $1/1000000)Gb"
elif [ $1 -ge 1000 ]; then
echo "$(scriptbc -p 2 $1/1000)Mb"
else
echo "${1}Kb"
fi
}
if [ $# -gt 1 ] ; then
echo "Usage: $0 [dirname]" >&2; exit 1
elif [ $# -eq 1 ] ; then
cd "$#"
fi
for file in *
do
if [ -d "$file" ] ; then
size=$(ls "$file"|wc -l|sed 's/[^[:digit:]]//g')
if [ $size -eq 1 ] ; then
echo "$file ($size entry)|"
else
echo "$file ($size entries)|"
fi
else
size="$(ls -sk "$file" | awk '{print $1}')"
echo "$file ($(gmk $size))|"
fi
done | \
sed 's/ /^^^/g' |\
xargs -n 2 |\
sed 's/\^\^\^/ /g' | \
awk -F\| '{ printf "%39s %-39s\n", $1, $2}'
exit 0
By the way, with respect to the book telling you to modify your PATH variable, that's really a bad idea, depending on what exactly it advised you to do. Just to be clear, never add your current directory to the PATH variable unless you intend on making that directory a permanent location for all of your scripts etc. If you are making this a permanent location for your scripts, make sure you add the location to the END of your PATH variable, not the beginning, otherwise you are creating a major security problem.
Linux and Unix do not add your current location, commonly called your PWD, or present working directory, to the path because someone could create a script called 'ls', for example, which could run something malicious instead of the actual 'ls' command. The proper way to execute something in your PWD, is to prepend it with './' (e.g. ./my_new_script.sh). This basically indicates that you really do want to run something from your PWD. Think of it as telling the shell "right here". The '.' actually represents your current directory, in other words "here".
I have a bash script that asks the user for 3 numbers (example, 123).
I'm stuck on how to separate these numbers in order to create file1, file2, file3, I also have to determine if they are unique.
Any help would be appreciated.
I can post my bash script if needed.
! /bin/bash
clear
echo -n "Enter three digits number: "
read number
echo $number | grep "^[0-9][0-9][0-9]$"
if [ "$?" -eq 1 ]
then
echo "Error!! Please enter only 3 numbers."
exit 1
fi
if [ -d ~/a2/numbers ]
then
rm -r ~/a2/numbers
fi
mkdir ~/a2/numbers
if [ ! -e ~/a2/products ]
then
echo "Error the file \'products\'! does not exist"
exit 1
fi
echo ' '
cat ~/a2/products
echo ' '
cut -f2 -d',' ~/a2/products > ~/a2/names
cat ~/a2/names
echo "I have $(cat ~/a2/names | wc -l) products in my product file"
echo ' '
You could use the command fold which will split your string by character. Example:
echo ${number} | fold -w1
To check if they are unique just use the if statement, because in your case you allow only three one digit numbers.
#!/bin/bash
read -p "enter 3 numbers: " nums
if [[ $nums != [0-9][0-9][0-9] ]]; then
echo "digits only please"
exit
fi
read n1 n2 n3 < <(sed 's/./& /g' <<< $nums)
if ((n1 == n2)) || ((n1 == n3)) || ((n2 == n3)); then
echo "no duplicate numbers"
exit
fi
For the first time the select display the options and it works fine but when I break from screenTwo function to come into this menu (previuos) it ask me for the selection but does not display the options, how can I handle this?
PS3="Please make a selection => " ; export PS3
select var in `awk -F "#" '{print $4}' ${Temp_Config_File} | uniq` PREVIOUS
do
echo "\n`date +"%d%m%Y%H%M%S"` Daemon $var selected " >> $Log_File
if [ -z $var ] ; then echo "\n\tPlease enter a valid choice \n " ; continue
else
if [ $var = "PREVIOUS" ]; then
#removeFiles
break
fi
screenTwo $var
fi
done
First Option : Please give me your idea.
Second option : Capture the return of screenTwo and whenever it is
break use awk to print the index with $4. (like below , but I dont
like it)
if [ $breakStat -eq 99 ]; then
i=1
echo "\n\nPlease choose one of the following deamon you wish to Start/Stop\n\n"
awk -F "#" '{print $4}' Temp_OPDaemon_Config.cfg | uniq | while read line
do
echo "${i}) ${line}"
let i=i+1
done
echo "${i}) PREVIOUS"
fi
Thanks
this is what I did to handle it .
PS3="Please make a selection => " ; export PS3
select var in `awk -F "#" '{print $4}' ${Temp_Config_File} | uniq` PREVIOUS
do
echo "${Date_Time} Daemon $var selected \n" >> $Log_File
if [ -z $var ] ; then echo "\n\tPlease enter a valid choice \n " ; continue
else
if [ $var = "PREVIOUS" ]; then
#removeFiles
break
fi
while :
do
screenTwo $var
breakStat=$?
if [ $breakStat -eq 99 ]; then
break
elif [ $breakStat -eq 98 ]; then
continue
fi
done
if [ $breakStat -eq 99 ]; then
echo "\n\nPlease choose one of the following deamon you wish to Start/Stop\n\n"
awk -F "#" '{print $4 }' ${Temp_Config_File} | uniq | awk -F "#" '{print NR ") " $0} END {print NR+1") PREVIOUS"}'
fi
fi
done