PPSS shell script - linux

I made a simple shell script to process mp3 files with SoX.
for f in ./*.mp3; do sox "$f" "${f%%.mp3}S.mp3" silence 1 0.02 1% -1 0.02 1%; done
The syntax should be like this:
sox in.wav out.wav silence 1 0.1 1% -1 0.1 1%
It will remove silence from the files I have in a folder, and create a new file with an "X" at the end (to distinguish from the original). I saved the script in my /bin folder and it works fine.
However, now I want to use it with PPSS, in order to run 8 instances in parallel. I cannot seem to get it working though, in the log file the error I keep getting is this error in the logs:
/usr/local/bin/ppss: line 2283: soxy.sh/Users/marw/Downloads/testfolder//ppss_dir/job_log/_Users_marw_Downloads_testfolder__10_audio_mp3: No such file or directory
Status: FAILURE
Total processing time (hh:mm:ss): 00:00:01
The PPSS syntax should be like this:
|P|P|S|S| Distributed Parallel Processing Shell Script 2.97
usage: /usr/local/bin/ppss [[ -d <sourcedir> | -f <sourcefile> ]] [[ -c '<command> "$ITEM"' ]]
[[ -C <configfile> ]] [[ -j ]] [[ -l <logfile> ]] [[ -p <# jobs> ]]
[[ -q ]] [[ -D <delay> ]] [[ -h ]] [[ --help ]] [[ -r ]] [[ --daemon ]]
Examples:
/usr/local/bin/ppss -d /dir/with/some/files -c 'gzip '
/usr/local/bin/ppss -d /dir/with/some/files -c 'cp "$ITEM" /tmp' -p 2
/usr/local/bin/ppss -f <file> -c 'wget -q -P /destination/directory "$ITEM"' -p 10
I'm new to shell scripting, forgive me if it's a stupid question. My OS is MacOS 10.11.5.
This is what I'm trying with PPSS:
ppss -d /Users/marw/Downloads/testfolder -c 'soxy.sh'
Maybe I have to write the my original script differently? It works fine without PPSS though.
EDIT:
I got a debug log here: http://pastebin.com/wak47rf8

The -c argument has to have a trailing space at the end. This works:
ppss -d /Users/marw/Downloads/testfolder -c 'soxy.sh '
Whereas this does not work:
ppss -d /Users/marw/Downloads/testfolder -c 'soxy.sh'
I got this from the PPSS wiki on Github:
The -c option specifies the command that will be executed by PPSS in
parallel for each file within the directory specified by -d. In this
example the command has a trailing space, which is necessary since the
command will expand to 'gzip example.tar' when executed. If the space
is omitted, an error will occur.

Related

Using an "if" statement with curl in terminal?

I'm using this command to get the response code of a page using curl:
curl -s -o /dev/null -w "%{http_code}" 'https://www.example.com'
If the response code is 200, then I want to delete a certain file on my computer. If it isn't 200, nothing should be done.
What's the easiest way to do this?
You can store the result in a shell variable (via command substitution), and then test the value with a simple if and [[ command. For example, in bash:
#!/bin/bash
code=$(curl -s -o /dev/null -w "%{http_code}" 'https://www.example.com')
if [[ $code == 200 ]]; then
rm /path/to/file
# other actions
fi
If all you want is a simple rm, you can shorten it to:
#!/bin/bash
[[ $code == 200 ]] && rm /path/to/file
In a generic POSIX shell, you'll have to use a less flexible [ command and quote the variable:
#!/bin/sh
code=$(curl -s -o /dev/null -w "%{http_code}" 'https://www.example.com')
if [ "$code" = 200 ]; then
rm /path/to/file
fi
Additionally, to test for a complete class of codes (e.g. 2xx), you can use wildcards:
#!/bin/bash
[[ $code == 2* ]] && rm /path/to/file
and the case command (an example here).

Any alternatives or ways to make this script faster?

I have this script which displays the terminal type being used. So for instance if you were running konsole it would display konsole. The script needs to go into another program that runs when a terminal is opened so it has to be very fast. Here's what I have so far
#!/bin/bash
shopt -s extglob
SHELLTTY=$(exec ps -p "$$" -o tty=)
P=$$
while read P < <(exec ps -p "$P" -o ppid=) && [[ $P == +([[:digit:]]) ]]; do
if read T < <(exec ps -p "$P" -o tty=) && [[ $T != "$SHELLTTY" ]]; then
ps -p "$P" -o comm=
break
fi
done
When the script is saved into a file it takes this long for it to run.
[~]$ time ./termgrab
konsole
real 0m0.063s
user 0m0.017s
sys 0m0.040s
The whole program itself takes .04 seconds so this slows it down considerably. Does anyone have any suggestions to make the script any faster or any alternative ways to achieve the same thing?

while in bash script

I am making a bash script. the objective is:
execute a program wait some seconds reset the program and repeat the process.
I make 2 scripts but i don't know where is the error...
#!/bin/bash
while true;
do
seg=`date +%M`;
if [[ "$seg" -eq "30" ]];
then killall sox;
echo "reset";
fi
done
bash: error sintáctico cerca del elemento inesperado `;'
#!/bin/bash
while true;
do
nice -n-10 sox -q -V0 --multi-threaded -t alsa hw:2,0 -t alsa pcm.default &&
done
bash: error sintáctico cerca del elemento inesperado `done'
Issues with Script #1:
The ; notation is to run multiple commands on the same line, one after another. Bash syntax requires that while and do on separate lines (same with if ... and then, and separated by ; if on the same line. Command statements are not normally terminated with a ; char in bash.
Change your code from:
#!/bin/bash
while true;
do
seg=`date +%M`;
if [[ "$seg" -eq "30" ]];
then killall sox;
echo "reset";
fi
done
To:
#!/bin/bash
while true
do
seg=`date +%M`
if [[ "$seg" -eq "30" ]]; then
killall sox
echo "reset"
fi
done
Issues with Script #2:
& means to run the command as a background process. && is used for conditional command chaining, as in: "If the previous command before && succeeds, then run the next command after the &&"
Change from:
#!/bin/bash
while true;
do
nice -n-10 sox -q -V0 --multi-threaded -t alsa hw:2,0 -t alsa pcm.default &&
done
To:
#!/bin/bash
while true
do
nice -n-10 sox -q -V0 --multi-threaded -t alsa hw:2,0 -t alsa pcm.default &
done

Validate script's argument by file extension?

I am writing a script which you can pass a file name into as an argument and it'll only run if it's a certain file extension.
flac2mp3 "01 Song.flac"
or
flac2mp3 "01 Song.FLAC"
I know there a lot of scripts out there showing you how to convert flac to mp3, but this is my script and I want to learn how to write the script using this method.
It's so I can learn arguments and for when I feel like converting only 1 individual file. (for multiple files I just wrote a for loop with *.flac inside the script)
I just want to learn how to check if the $1 argument contains *.[Ff][Ll][Aa][Cc]
Here's what I cobbled up together from the internet so far (which I know is embarrassingly wrong but I wanted to show what I was going for) :
#!/bin/bash
#flac2mp3
if [ -z $1 ] && [[$1 !=~ *.[Ff][Ll][Aa][Cc]]];then echo "Give FLAC File Name"; exit 0;fi
OUTF=${1%.flac}.mp3
ARTIST=$(metaflac "$1" --show-tag=ARTIST | sed s/.*=//g)
TITLE=$(metaflac "$1" --show-tag=TITLE | sed s/.*=//g)
ALBUM=$(metaflac "$1" --show-tag=ALBUM | sed s/.*=//g)
GENRE=$(metaflac "$1" --show-tag=GENRE | sed s/.*=//g)
TRACKNUMBER=$(metaflac "$1" --show-tag=TRACKNUMBER | sed s/.*=//g)
DATE=$(metaflac "$1" --show-tag=DATE | sed s/.*=//g)
flac -c -d "$1" | lame -m j -q 0 --vbr-new -V 0 -s 44.1 - "$OUTF"
id3 -t "$TITLE" -T "${TRACKNUMBER:-0}" -a "$ARTIST" -A "$ALBUM" -y "$DATE" -g "${GENRE:-12}" "$OUTF"
done
Please and Thank Your for the help.
Try the following code:
shopt -s nocasematch
if [[ $1 == *flac ]]; then
echo "ok"
fi
This is case insensitive.
EDIT
$ LANG=C help shopt
shopt: shopt [-pqsu] [-o] [optname ...]
Set and unset shell options.
Change the setting of each shell option OPTNAME. Without any option
arguments, list all shell options with an indication of whether or not each
is set.
Options:
-o restrict OPTNAMEs to those defined for use with `set -o'
-p print each shell option with an indication of its status
-q suppress output
-s enable (set) each OPTNAME
-u disable (unset) each OPTNAME
Exit Status:
Returns success if OPTNAME is enabled; fails if an invalid option is
given or OPTNAME is disabled.
If you run shopt alone in a shell, you will see al options available :
$ shopt
autocd on
cdable_vars on
cdspell off
checkhash off
checkjobs off
checkwinsize off
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
direxpand off
dirspell off
dotglob on
execfail off
expand_aliases on
extdebug off
extglob on
extquote on
failglob off
force_fignore on
globstar on
gnu_errfmt off
histappend on
histreedit off
histverify off
hostcomplete off
huponexit off
interactive_comments on
lastpipe off
lithist off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
To know what does all these options :
man bash | less +/'^SHELL BUILTIN COMMANDS'
then search `shopt from within this section.

Bash Script to allow Nagios to report ping between two other Linux machines

I'm looking for alternatives to working out the ping between two machine (mA and mB) and report this back to Nagios (on mC).
My current thoughts are to write a BASH script that will ping the machines in a cron job, output the data to a file then have another bash script that Nagios can use to read that file. This doesn't feel like the best/right way to do this though?
Here's the script I plan to run in the cron job:
#!/bin/bash
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]
then
echo $0: usage: $0 file? ip? pingcount? deadline?
exit 126
else
FILE=$1
IP=$2
PCOUNT=$3
DLINE=$4
while read line
do
if [[ $line == rtt* ]]
then
#replace forward slash with underscore
line=${line////_}
#replace spaces with underscore
line=${line// /_}
#get the 8 item when splitting string on underscore
#echo $line| cut -d'_' -f 8 >> $FILE #Append
#echo $line| cut -d'_' -f 8 > $FILE #Overwrite
echo $line| cut -d'_' -f 8
fi
done < <(ping $IP -c $PCOUNT -q -w $DLINE) #-q output summary / -w deadline / -c pint count
I though about using trace route, but I think this would be produces a slower ping?, is there another way to achieve what I want?
Note: I know Nagios can directly ping a machine, but this isn't what I want to do and won't tell me what I want. Also this is my second script ever, so it's probably rubbish. Also, what alternative would I have if ICMP was blocked?
Have you looked at NRPE and check_ping? This would allow the nagios machine (mC) to ask mA to ping mB and then mA would report the results to mC. You would need to install and configure NRPE and the nagios-plugins on mA for this to work.

Resources