Problem with bash script that show volume level - linux

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

Related

Looping script, redirect to file

So I have this BASH script and what i want to do is, reach out to the servers. Check the used % of a directory. If it is higher than my set threshold (90) then print that server name to another file on the server where the script has been run from.
What it is doing is printing the first server name twice in to the file so it looks like
server1
server2
Here is my script ... I don't see why it would be going around in a loop to that first server twice
#!/bin/bash
SERVERS="server1
server2"
for i in $SERVERS; do
ssh $SERVERS "
df -h | grep var | awk '{print \$4}' | sed 's/%//g' > /home/user/space.txt
RESULTS=\$(grep -E "1[5-9]" /home/user/space.txt)
THRESHOLD=90
if [[ \$RESULTS -lt \$THRESHOLD ]]; then
exit 1;
elif [[ \$RESULTS -gt \$THRESHOLD ]]; then
hostname;
fi
" >> /home/user/problem.txt
done
Try this,
#!/bin/bash
SERVERS="server1
server2"
for i in $SERVERS; do
ssh "$i" "
df -h | grep var | awk '{print \$4}' | sed 's/%//g' > /home/user/space.txt
RESULTS=\$(grep -E "1[5-9]" /home/user/space.txt)
THRESHOLD=90
if [[ \$RESULTS -lt \$THRESHOLD ]]; then
exit 1;
elif [[ \$RESULTS -gt \$THRESHOLD ]]; then
hostname;
fi
" >> /home/user/problem.txt
done

I need some assistance in figuring out how to retrieve files through the usage of my bash script

Although I was able to figure out my first script and get it to run, I am having issues with my second script. Basically I need to retrieve my deleted files and restore them in my created home directory. I was able to get some of question 2, and all of 3 and 4 to work successfully. The issue I have with question 2 is if I type up the file that I want to restore, it will pull up the file and inode number which is fine. However, if I run the script without the desired file, it will show a bunch of inodes and the command "Missing Operand". The missing operand command is one that I want since I created it in order to test that the files I want to restore exist. I have attached my code below. Again, I wonder what I got wrong. I did some of the suggestions shellcheck offered but I still got the same results.
Here is my code:
#!/bin/bash
#2.
fileName=$1
inode=$(ls -i $1 | cut -d " " -f1)
echo "safe_rm_restore $1_$inode"
#3.
function movingfile(){
if [ -e $HOME/deleted ] ;
then
mv $1_$inode $HOME/deleted $(grep $1 $HOME/.restore.info | cut -d" " -f3)
fi
}
movingfile $1
#4.
function safe(){
filename=$1
if [ ! -e $1 ] ;
then
echo "safe_rm_restore :cannot restore '$1': No such file or directory"
exit 1
elif [ $# -eq 0 ] ;
then
echo "safe_rm_restore: cannot restore '$1' : Missing operand"
exit 1
fi
}
safe $1
##5.
function restoreFile(){
if [ -e $(grep $1 $HOME/.restore.info | cut -d" " -f2) ] ;
then
read -p "File currently exists. Do you want to overwrite y/n?: word"
if [[ $word = "yes" || $word = "Y" || $word = "y" ]] ;
then
rm $(grep $1 $HOME/.restore.info | cut -d" " -f2)
mv $HOME/deleted $(grep $1/.restore.info | cut -d" " -f2)
fi
if [[ $word = "n" ]] ;
then
rm $1
exit 0
else
echo "Invalid Option"
exit 1
fi
fi
}
restoreFile $1
##6.
function restored(){
remove=$(grep -v $1 $HOME/.restore.info | tee $HOME/.restore.info)
if [[ ! -e $HOME/deleted && -e $(grep $1 $HOME/.restore.info | -d":" -f2)]];
then
$remove
fi
}
restored $1
I've followed the suggestions that you all gave me (and it moved me towards the right direction) but I still had some issues getting my operations to fully work. For instance, if no file name was given, my script was supposed to say Missing Operand but instead it gives all inode numbers in my file and my script freezes for sometime. Here is my updated second bash script. The indention looks great from my UNIX system but is somehow skewed when I transfer it on here. Thank you again!
#!/bin/bash
##2.
fileName="$1"
inode="$(ls -i $1 |cut -d" " -f1)"
echo "safe_rm_restore $1_$inode"
touch "$1"
##3.
movingfile(){
if [ -e $HOME/deleted ] ;
then
touch $1_$inode
mv $1_$inode $HOME/deleted $(grep $1 $HOME/.restore.info | cut -d" " -f4)
else
exit 1
fi
}
movingfile $1
##4.
safe(){
filename=$1
if [ ! -e $1 ] ;
then
echo "safe_rm_restore :cannot restore '$1': No such file or directory"
exit 1
elif [ $# -eq 0 ] ;
then
echo "safe_rm_restore: cannot restore '$1' : Missing operand"
exit 1
fi
}
safe $1
##5.
restoreFile(){
if [ -e $(grep $1 $HOME/.restore.info | cut -d" " -f4) ] ;
then
read -p "File currently exists. Do you want to overwrite y/n?:" word
if [[ $word = "yes" || $word = "Y" || $word = "y" ]] ;
then
mv $1_$inode $HOME/project $(grep $1/.restore.info | cut -d" " -f4)
fi
if [[ $word = "n" ]] ;
then
rm -r $1_$inode
exit 0
else
echo "Invalid Option"
exit 1
fi
fi
}
restoreFile $1
##6.
restored(){
remove=$(grep -v $1 $HOME/.restore.info | tee $HOME/.restore.info)
if [[ ! -e $HOME/deleted && -e $(grep $1 $HOME/.restore.info |cut -d":" -f4) ]];
then
$remove
fi
}
restored $1

Bash offer numberd results for selection to user

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`

Possible to turn 10 similar functions into a for loop?

I am trying to pipe information from my workspaces into another command, and because each workspace contains the same information, with only a different number to identify it, I have written 10 functions where the only difference is one character inside some variable names. I feel like this can be greatly simplified, but I cannot figure out how to get any sort of loop working in my situation.
All here is my script containing the 10 functions:
#!/bin/bash
# Include config file.
. $(dirname $0)/config
getWorkspaceInfo(){
filledWorkspaces=$(i3-msg -t get_workspaces | grep -Po '"'"name"'"\s*:\s*"\K([^"]*)')
currentWorkspace=$(i3-msg -t get_outputs | sed 's/.*"current_workspace":"\([^"]*\)".*/\1/')
}
# Determine the status of each workspace. Current is green, unfocused is white, empty is grey.
workspace1(){
if [[ ${currentWorkspace} -eq 1 ]]; then
workspace1Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "1") == "" ]]; then
workspace1Color=${grey}
else
workspace1Color=${foreground}
fi
echo "%{F${workspace1Color}}${workspace1Name}"
}
workspace2(){
if [[ ${currentWorkspace} -eq 2 ]]; then
workspace2Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "2") == "" ]]; then
workspace2Color=${grey}
else
workspace2Color=${foreground}
fi
echo "%{F${workspace2Color}}${workspace2Name}"
}
workspace3(){
if [[ ${currentWorkspace} -eq 3 ]]; then
workspace3Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "3") == "" ]]; then
workspace3Color=${grey}
else
workspace3Color=${foreground}
fi
echo "%{F${workspace3Color}}${workspace3Name}"
}
workspace4(){
if [[ ${currentWorkspace} -eq 4 ]]; then
workspace4Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "4") == "" ]]; then
workspace4Color=${grey}
else
workspace4Color=${foreground}
fi
echo "%{F${workspace4Color}}${workspace4Name}"
}
workspace5(){
if [[ ${currentWorkspace} -eq 5 ]]; then
workspace5Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "5") == "" ]]; then
workspace5Color=${grey}
else
workspace5Color=${foreground}
fi
echo "%{F${workspace5Color}}${workspace5Name}"
}
workspace6(){
if [[ ${currentWorkspace} -eq 6 ]]; then
workspace6Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "6") == "" ]]; then
workspace6Color=${grey}
else
workspace6Color=${foreground}
fi
echo "%{F${workspace6Color}}${workspace6Name}"
}
workspace7(){
if [[ ${currentWorkspace} -eq 7 ]]; then
workspace7Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "7") == "" ]]; then
workspace7Color=${grey}
else
workspace7Color=${foreground}
fi
echo "%{F${workspace7Color}}${workspace7Name}"
}
workspace8(){
if [[ ${currentWorkspace} -eq 8 ]]; then
workspace8Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "8") == "" ]]; then
workspace8Color=${grey}
else
workspace8Color=${foreground}
fi
echo "%{F${workspace8Color}}${workspace8Name}"
}
workspace9(){
if [[ ${currentWorkspace} -eq 9 ]]; then
workspace9Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "9") == "" ]]; then
workspace9Color=${grey}
else
workspace9Color=${foreground}
fi
echo "%{F${workspace9Color}}${workspace9Name}"
}
workspace10(){
if [[ ${currentWorkspace} -eq 10 ]]; then
workspace10Color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "10") == "" ]]; then
workspace10Color=${grey}
else
workspace10Color=${foreground}
fi
echo "%{F${workspace10Color}}${workspace10Name}"
}
# Pipe functions to the bar infinitely.
while true; do
getWorkspaceInfo
echo "%{c}$(workspace1)${separator}$(workspace2)${separator}$(workspace3)${separator}$(workspace4)${separator}$(workspace5)${separator}$(workspace6)${separator}$(workspace7)${separator}$(workspace8)${separator}$(workspace9)${separator}$(workspace10)"
done | lemonbar -g ${panelWidth}x${panelHeight}+${panelX}+${bottomPanelY} -f "${font}" -f "${iconFont}" -B "${background}" -F "${foreground}" -p -d | \
while true; do read line; eval $line; done &
Here is the config file that I am importing:
#!/bin/bash
# Outside sources
xres="$HOME/.Xresources"
i3config="$HOME/.config/i3/config"
# Fetch information from Xresources
background=$(cat ${xres} | grep -i background | tail -c 8)
foreground=$(cat ${xres} | grep -i foreground | tail -c 8)
black=$(cat ${xres} | grep -i color0 | tail -c 8)
grey=$(cat ${xres} | grep -i color8 | tail -c 8)
red=$(cat ${xres} | grep -i color9 | tail -c 8)
green=$(cat ${xres} | grep -i color10 | tail -c 8)
yellow=$(cat ${xres} | grep -i color11 | tail -c 8)
blue=$(cat ${xres} | grep -i color12 | tail -c 8)
magenta=$(cat ${xres} | grep -i color13 | tail -c 8)
cyan=$(cat ${xres} | grep -i color14 | tail -c 8)
white=$(cat ${xres} | grep -i color15 | tail -c 8)
# Fetch information from i3 config
gapSize=$(cat ${i3config} | grep -i "gaps inner" | awk '{print $3}')
# Workspace names -- independant from i3 config -- workspaces in i3 config should be named numbers 1-10.
workspace1Name="Web Browser"
workspace2Name="Terminal"
workspace3Name="Text Editor"
workspace4Name="Unspecified"
workspace5Name="Unspecified"
workspace6Name="Unspecified"
workspace7Name="Unspecified"
workspace8Name="Unspecified"
workspace9Name="Messenger"
workspace10Name="Music Player"
# Fonts
font="InputSans-10"
iconFont="FontAwesome"
separator="%{F$foreground} |│| "
# Panel size
screenWidth=$(xrandr | grep 'Screen 0'| awk '{print $8}')
screenHeight=$(xrandr | grep 'Screen 0' | awk '{print $10}' | tr -d ",")
panelHeight=$((${gapSize} * 2))
panelWidth=$((${screenWidth} - ${panelHeight}))
panelX=${gapSize}
topPanelY=${gapSize}
bottomPanelY=$((${screenHeight} - ${panelHeight} - ${gapSize}))
Well, the simplest fix is to write something like:
function all_10_workspaces () {
local i
for i in {1..10} ; do
local workspaceNameVar="workspace${i}Name"
local workspaceName="${!workspaceNameVar}"
local color
if (( currentWorkspace == 1 )) ; then
color=$green
elif grep -w -q "$i" <<< "$filledWorkspaces" ; then
color=$foreground
else
color=$grey
fi
echo "%{F$color}$workspaceName"
done
}
. . . however, you should really consider using arrays instead. For example:
workspaceNames=(
'' # 0 (no such workspace)
'Web Browser' # 1
Terminal # 2
'Text Editor' # 3
Unspecified # 4
Unspecified # 5
Unspecified # 6
Unspecified # 7
Unspecified # 8
Messenger # 9
'Music Player' # 10
)
Then, for example, workspace #7 is named "${workspaceNames[7]}", and given a variable i, workspace #i is named "${workspaceNames[i]}".
Something like this, perhaps?
workspaceCount=10
while true; do
# Output will look like "%{c}$(workspace1Color)${separator}$(workspace2Color)${separator}...."
# This is what is sent before the first item in each line
itemSep="%{c}"
for i in {1..$workspaceCount}; do
if [ ${currentWorkspace} -eq $i ]; then
color="${green}"
elif [[ $(echo ${filledWorkspaces} | grep -w "1") == "" ]]; then
color="${grey}"
else
color="${foreground}"
fi
echo -n "${itemSep}${color}"
itemSep="${separator}"
done
echo # Send LF after all items
done
I figured out a way to get what I wanted using ideas from both ruakh and Phil Freed as well as something I came up with on my own. This may not be the shortest or most efficient way to solve the problem, but it is much shorter than having 10 separate functions.
#!/bin/bash
# Include config file.
. $(dirname $0)/config
getWorkspaceInfo(){
filledWorkspaces=$(i3-msg -t get_workspaces | grep -Po '"'"name"'"\s*:\s*"\K([^"]*)')
currentWorkspace=$(i3-msg -t get_outputs | sed 's/.*"current_workspace":"\([^"]*\)".*/\1/')
}
# Determine the status of each workspace. Current is green, unfocused is white, empty is grey.
workspaces(){
workspaces=""
currentSeparator="${separator}"
for i in {1..10} ; do
if [[ ${currentWorkspace} -eq ${i} ]]; then
color=${green}
elif [[ $(echo ${filledWorkspaces} | grep -w "${i}") == "" ]]; then
color=${grey}
else
color=${foreground}
fi
if [[ ${i} -eq 10 ]]; then
currentSeparator=""
fi
workspaces+="%{F$color}${workspaceNames[i]}${currentSeparator}"
done
echo "${workspaces}"
}
# Pipe functions to the bar infinitely.
while true; do
getWorkspaceInfo
echo "%{c}$(workspaces)"
done | lemonbar -g ${panelWidth}x${panelHeight}+${panelX}+${bottomPanelY} -f "${font}" -f "${iconFont}" -B "${background}" -F "${foreground}" -p -d | \
while true; do read line; eval $line; done &
To explain what it does as simply as possible:
Loop through all 10 workspaces, adding what would have been the output of a single function to the end of a new variable. Since I cannot add a separator between each function call anymore, I simply added the separator to the end of the echo, making sure that no separator is added to the last workspace by using a for loop, which sets the separator variable to null.

Linux bash script -

I am trying to use whether or not a line contains a date as a condition for an if statement:
if [grep -n -v '[0-9][0-9][0-9][0-9]' $line |wc -l==0]
then
...
The above returns an error. I don't necessarily need to use grep. The line processed by grep would look like:
1984 Dan Marino QB Miami Dolphins
Any help is appreciated.
if [[ $(echo $line | grep -q '[0-9][0-9][0-9][0-9]') ]]; then
# do something
fi
You can check this using bash built-ins:
re='\b[[:digit:]]{4}\b'
if [[ $line =~ $re ]] ; then
echo ok;
fi
[grep -n -v '[0-9][0-9][0-9][0-9]' $line |wc -l==0]
problem 1: [(space).....(space)] you need those spaces
problem 2: there is no [ foo==bar ] you can do something like [ $(echo "0") = "0" ] or [[ $(echo "0") == 0 ]] here the $(echo "0") is an example, you should fill with your commands.
You can just call grep with -q option and check the return value:
if [ $(grep -qv '[0-9][0-9][0-9][0-9]' $line) -eq 0 ]; then
# ...
fi
Use command substitution and proper bash syntax.
[[ "`grep -n -v '[0-9][0-9][0-9][0-9]' $line | wc -l`" -eq 0 ]]

Resources