Suggestions how to check for presence of a audio CD-ROM before continuing the script - bash

I have found a nice solution to check if an audio cd is present. It works with a While loop which I like to end after the audio rip is done and the disc is ejected.
while true; do
sleep 10
cdparanoia -Q 2>&1 | grep 'audio only'
RET=$?
if [ $RET = "0" ] ; then
abcde -c ~/Music/abcde.conf -o flac,mp3,ogg -p -x
fi
done

I believe I found a solution to my wishes, hereby my code
#!/bin/bash
echo "voer componist in"
read componist
echo ingevoerde "$componist"
echo "voer het aantal CD's in"
read aantaldiscs
echo aantal discs $aantaldiscs
mkdir ~/Music/"$componist"
for a in $(seq -f %02g 01 $aantaldiscs);
do
mkdir ~/Music/"$componist"/$a
echo "OUTPUTDIR='~/Music/"$componist"/$a'" > ~/Music/abcde.conf
echo "OUTPUTFORMAT='\${TRACKNUM}.\${TRACKFILE}'" >> ~/Music/abcde.conf
echo "LAMEOPTS='-V 0'" >> ~/Music/abcde.conf
echo "FLACOPTS='-f --verify --best'" >> ~/Music/abcde.conf
echo "OGGENCOPTS='-q 8'" >> ~/Music/abcde.conf
echo "MAXPROCS=2" >> ~/Music/abcde.conf
echo "mungefilename ()" >> ~/Music/abcde.conf
echo "{" >> ~/Music/abcde.conf
echo "echo "$#" | sed s,:,\ -,g | tr / _ | tr -d \’\"\?\[:cntrl:\]" >> ~/Music/abcde.conf
echo "}" >> ~/Music/abcde.conf
while true; do
sleep 10
cdparanoia -Q 2>&1 | grep 'audio only'
RET=$?
if [ $RET = "0" ] ; then
abcde -c ~/Music/abcde.conf -o flac,mp3,ogg -p -x
break
fi
done
done

Related

bash optional command in variable

i have a code:
L12(){
echo -e "/tftpboot/log/archive/L12/*/*$sn*L12*.log /tftpboot/log/diag/*$sn*L12*.log"
command="| grep -v hdd"
}
getlog(){
echo $(ls -ltr $(${1}) 2>/dev/null `${command}` | tail -1)
}
however $command does not seem to be inserting | grep -v hdd correctly
i need $command to be either empty or | grep
is there a simple solution to my issue or should i go for different approach
edit:
there may be another problem in there
i am loading a few "modules"
EVAL.sh
ev(){
case "${1}" in
*FAIL*) paint $red "FAIL";;
*PASS*) paint $green "PASS";;
*)echo;;
esac
result=${1}
}
rackinfo.sh (the "main script")
#! /bin/bash
#set -x
n=0
for src in $(ls modules/)
do
source modules/$src && ((n++))
## debugging
# source src/$src || ((n++)) || echo "there may be an issue in $src"
done
## debugging
# x=($n - $(ls | grep src | wc -l))
# echo -e "$x plugin(s) failed to laod correctly"
# echo -e "loaded $n modules"
########################################################################
command=cat
tests=("L12" "AL" "BI" "L12-3")
while read sn
do
paint $blue "$sn\t"
for test in ${tests[#]}
do
log="$(ev "$(getlog ${test})")"
if [[ -z ${log} ]]
then
paint $cyan "${test} "; paint $red "!LOG "
else
paint $cyan "${test} ";echo -ne "$log "
fi
done
echo
done <$1
the results i get are still containing "hdd" for L12()
Set command to cat as a default.
Also, it's best to use an array for commands with arguments, in case any of the arguments is multiple words.
There's rarely a reason to write echo $(command). That's essentially the same as just writing command.
#default command does nothing
command=(cat)
L12(){
echo -e "/tftpboot/log/archive/L12/*/*$sn*L12*.log /tftpboot/log/diag/*$sn*L12*.log"
command=(grep -v hdd)
}
getlog(){
ls -ltr $(${1}) 2>/dev/null | "${command[#]}" | tail -1)
}

using tail to follow a log and execute a command instantly? Only seems to work by starting a new line

I am trying to figure out a command which will enable me to read a log file in real time and execute a command when the string matches? I am using logkeys and trying to make it when I type a word it immediately triggers a command. This script works, but only when I press enter (start a newline) does it execute, and it seems anything I have found online also requires the press of the enter key to work. Is there a way to get around this somehow?
#/bin/bash
echo Waiting...
string='test'
tail /path/to/logfile -n0 -f | while read line; do
if [[ $line =~ $string ]]; then
echo "hello"
fi
done
I've played with buffering settings to no avail, so my conclusion is that read waits for a newline before it finishes. If you instead did read -n1, read would read exactly one character, which isn't quite what we want either, because then $line would always be just that one char.
Unfortunately, grep appears to have the same behavior (even with buffering options changed), even with grep -o:
$ tail logfile -f -n0 | grep -o test &
[1] 25524
$ echo -n test >> logfile
$ echo -n test >> logfile
$ echo test >> logfile
test
test
test
I think the general solution would be to roll our own "ring buffer grep" search tool that reads character per character into a ring buffer.
Here's my perl version of that, hope it helps. (Save as: ringgrep.pl)
#!/usr/bin/perl -w
use strict;
if (!$ARGV[0]) {
print "Usage: $0 needle\n";
exit 1;
}
my $needle = $ARGV[0];
my $buffer_len = length($needle);
my #buffer = (0) x $buffer_len;
my $i = 0;
my $input;
while(sysread(STDIN, $input, 1)) {
$buffer[$i] = $input;
my $string = join("", #buffer);
$string = (($i+1)%$buffer_len == 0 ? "" : substr($string, $i-$buffer_len+1)) . substr($string, 0, $i+1);
# print "string is: $string\n";
if ($string =~ /$needle/) {
print "got test!\n";
#buffer = (0) x $buffer_len;
$i = 0
} else {
$i = (++$i) % $buffer_len
}
}
Usage:
$ chmod +x ringgrep.pl
$ tail logfile -n0 -f | ./ringgrep.pl "this is a test" &
[1] 25756
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ (echo -n t; echo -n h; echo -n i; echo -n s; echo -n ' '; echo -n i; echo -n s; echo -n ' '; echo -n a; echo -n ' '; echo -n t; echo -n e; echo -n s; echo -n t) >> logfile
got test!

bash script, command "select" hold scrolling

I have this bash script I would like to pause so I can read what is echoed. I use this on a mobile phone so the screen is very small. The continent output is in 2 colums by default, can I do this with the city output aswell
I tried putting " | more " before && but it didn't work.
normaly I put everything in functions() but finding the select command here on stackoverflow.com made it much faster.
#!/bin/bash
PS3=" Enter a Number "
dir=/usr/share/zoneinfo
echo
echo " Please select your Continent "
echo
select continent in $dir/* ; do
test -n "$continent" && break;
echo ">>> Invalid Selection";
done
selected_cont=($(echo "$continent" | grep -Eo '[^/]+/?$' | cut -d'/' -f2 ))
echo
echo " Selected $selected_cont as your Continent "
echo
echo " Please select nearest city "
select city in $continent/* ; do
test -n "$city" && break;
echo ">>> Invalid Selection";
done
echo
selected_city=($(echo "$city" | grep -Eo '[^/]+/?$' | cut -d'/' -f2 ))
timezone="$selected_cont/$selected_city"
echo
echo
echo " $timezone is selected as your timezone "
#echo "show Continent: $continent"
#echo "show City: $city"
sleep 2
#echo export TZ=$city >> $HOME/.bashrc
#sudo ln -sf $city /etc/localtime
This was my first working try
#!/bin/bash
dir=("/usr/share/zoneinfo/")
continent=$(dialog --stdout --title "Select Continent" --dselect $dir 0 0 --no-mouse --aspect 9 --ascii-lines)
city=$(dialog --stdout --title "Please choose a file" --fselect $continent/ 14 48)
#echo ${continent} selected
#echo ${city} selected
selected_cont=($(echo ${continent} | grep -Eo '[^/]+/?$' | cut -d'/' -f2))
# Strip full path to last directory to get the continent. use it with $selected_continent
selected_city=($(echo ${city} | grep -Eo '[^/]+/?$' | cut -d'/' -f2))
# Strip full path to last directory to get the nearest city. use it with $selected_city
# echo "export TZ=(${continent/${city})" >> $HOME/.bashrc
# sudo ln -sf ${city} /etc/localtime
echo $selected_cont selected as continent
echo selected $selected_city as nearest city
echo "set TZ in bashrc TZ=$selected_cont/$selected_city "
echo "link ${city} to /etc/localtime "
########EOF###########
This is my second try with directory and file check
#!/bin/bash
start() {
if [[ -z $selected_cont ]]; then
continent=($(dialog --stdout --title "Select Continent" --dselect $dir 0 0 --no-mouse --aspect 9 --ascii-lines));
selected_cont=($(echo ${continent} | grep -Eo '[^/]+/?$' | cut -d'/' -f2));
if [[ -d $dir$selected_cont ]]; then
echo $dir$selected_cont
start
else
selected_cont=
start
fi
elif [[ -z $selected_city ]]; then
city=($(dialog --stdout --title "Please choose a file" --fselect $continent/ 14 48));
selected_city=($(echo ${city} | grep -Eo '[^/]+/?$' | cut -d'/' -f2));
if [[ -f ${city} ]]; then
echo $selected_city
start
else
selected_city=
start
fi
else
# echo "export TZ=(${continent/${city})" >> $HOME/.bashrc
# sudo ln -sf ${city} /etc/localtime
echo $selected_cont selected as continent
echo selected $selected_city as nearest city
echo "set TZ in bashrc TZ=$selected_cont/$selected_city "
echo "link ${city} to /etc/localtime "
fi
}
start
######EOF######
This 2nd one is preferred but it errors on line 6 continent= Error: Expected a box option. The script continuous as wanted and the result is as wanted.
Can anyone clarify the error as I use the same variable in script one without errors?
I've updated to output to a temp file no errors in this script
#!/bin/bash
dir=("/usr/share/zoneinfo/")
temp=/tmp/test.$$
start() {
if [[ -z $selected_cont ]]; then
continent=($(dialog --stdout --title "Select Continent" --dselect $dir 0 0 --no-mouse --aspect 9 --ascii-lines 2>&1 > $temp));
selected_cont=($(cat $temp | grep -Eo '[^/]+/?$' ));
echo
if [[ -d $dir$selected_cont ]]; then
start
else
selected_cont=
start
fi
elif [[ -z $selected_city ]]; then
city=($(dialog --stdout --title "Please choose a file" --fselect $dir$selected_cont/ 0 0 2>&1 > $temp));
selected_city=($(cat $temp | grep -Eo '[^/]+/?$' ));
if [[ -f $(cat $temp) ]]; then
start
else
selected_city=
start
fi
else
# echo "export TZ=(${continent/${city})" >> $HOME/.bashrc
# sudo ln -sf $(cat $temp) /etc/localtime
echo $selected_cont selected as continent
echo selected $selected_city as nearest city
echo "set TZ in bashrc TZ=$selected_cont/$selected_city "
echo link $(cat $temp) to /etc/localtime
fi
}
start

Syntax error: “(” unexpected (expecting “fi”)

filein="users.csv"
IFS=$'\n'
if [ ! -f "$filein" ]
then
echo "Cannot find file $filein"
else
#...
groups=(`cut -d: -f 6 "$filein" | sed 's/ //'`)
fullnames=(`cut -d: -f 1 "$filein"`)
userid=(`cut -d: -f 2 "$filein"`)
usernames=(`cut -d: -f 1 "$filein" | tr [A-Z] [a-z] | awk '{print substr($1,1,1) $2}'`)
#...
for group in ${groups[*]}
do
grep -q "^$group" /etc/group ; let x=$?
if [ $x -eq 1 ]
then
groupadd "$group"
fi
done
#...
x=0
created=0
for user in ${usernames[*]}
do
useradd -n -c ${fullnames[$x]} -g "${groups[$x]}" $user 2> /dev/null
if [ $? -eq 0 ]
then
let created=$created+1
fi
#...
echo "${userid[$x]}" | passwd --stdin "$user" > /dev/null
#...
echo "Welcome! Your account has been created. Your username is $user and temporary
password is \"$password\" without the quotes." | mail -s "New Account for $user" -b root $user
x=$x+1
echo -n "..."
sleep .25
done
sleep .25
echo " "
echo "Complete. $created accounts have been created."
fi
I'm guessing the problem is that you're trying to capture command output in arrays without actually using command substitution. You want something like this:
groups=( $( cut... ) )
Note the extra set of parentheses with $ in front of the inner set.

Shell script for generating HTML out put

The following script is generating the desired out put but not redirecting the result to /home/myuser/slavedelay.html
#!/bin/bash
host=<ip>
echo $host
user=usr1
password=mypass
threshold=300
statusok=OK
statuscritical=CRITICAL
for i in ert7 ert9
do
echo "<html>" > /home/myuser/slavedelay.html
if [ "$i" == "ert7" ]; then
slvdelay=`mysql -u$user -p$password -h<ip> -S /backup/mysql/mysql.sock -e 'show slave status\G' | grep Seconds_Behind_Master | sed -e 's/ *Seconds_Behind_Master: //'`
if [ $slvdelay -ge $threshold ]; then
echo "<tr><td>$i</td><td>CRITICAL</td>" >> /home/myuser/slavedelay.html
echo "<tr><td>$i</td><td>CRITICAL</td>"
else
echo "<tr><td>$i</td><td>OK</td>" >> /home/myuser/slavedelay.html
echo "<tr><td>$i</td><td>OK</td>"
fi
fi
done
echo "</html>" >> /home/myuser/slavedelay.html
If I cat the output file /home/myuser/slavedelay.html it gives.
<html>
</html>
Execution result :
sh slave_delay.sh
<tr><td>sdb7</td><td>OK</td>
Each time through the loop you're emptying the output file because of the command
echo "<html>" > /home/myuser/slavedelay.html
So the first iteration writes the <tr> row to the file, then the next iteration overwrites the file and doesn't write those lines because $i isn't ert7.
Change it to:
for i in ert7 ert9
do
if [ "$i" == "ert7" ]; then
echo "<html>" > /home/myuser/slavedelay.html
slvdelay=`mysql -u$user -p$password -h<ip> -S /backup/mysql/mysql.sock -e 'show slave status\G' | grep Seconds_Behind_Master | sed -e 's/ *Seconds_Behind_Master: //'`
if [ $slvdelay -ge $threshold ]; then
echo "<tr><td>$i</td><td>CRITICAL</td>"
else
echo "<tr><td>$i</td><td>OK</td>"
fi | tee -a /home/myuser/slavedelay.html
echo "</html>" >> /home/myuser/slavedelay.html
fi
done
Replace :
if [ "$i" == "ert7" ];
with:
if [ "$i" = "ert7" ];
You use = operator in test also.

Resources