Checking for result when using < sqlite3 - command-line

I need to know if this command is either successful or failure, inside a script .sh file.
sqlite3 database.db < database.sql
I'm thinking something like:
$result = ('sqlite3 database.db < database.sql')
where if the $result contains something, I bail. Else if the result does not contain anything, I continue on.

The sqlite3 tool will return the normal error status, which you can check with the normal shell methods (if, $?, etc.):
$ if sqlite3 test.db "select 42;"; then echo success; else echo failure; fi
42
success
$ if sqlite3 test.db "select x;"; then echo success; else echo failure; fi
Error: no such column: x
failure

Related

mysqldump in perl - return value is allways 0

When I perform following in perl, I allways get the error code "0". Even if for example the mysql database does not exist, or the password is wrong, etc.
#args = ("mysqldump -u root -ppassword database1 | gzip -c > /usr/local/bin/database.gzip");
system(#args) == 0
or die "Command failed: #args \nError Code: $? \n";
My goal is to catch any error of the mysqldump command, so I can make sure if the backup was successfuly.
I guess it is the pipe that is giving this problem. You might be getting the exit status of
"gzip -c > /usr/local/bin/database.gzip"
You might have to split the dump and gzip part into two.
use
`mysqldump -u root -ppassword database1 > ./dump.txt`;
if ($? == 0){
`gzip -9 ./dump.txt`;
}
else{
die "errored";
}

comparison the content of a text and csv files

I need a sample bash script to compare a first line of a file(Result.txt) to first row and column of another file(table.csv), then send the result to an html file.
I am very basic in coding, this is what I found so far:
#!/bin/sh
Result.txt="$(head -n 1 < $1|tail -n 1)"
table.csv="$(head -n 1 < $2|tail -n 1)"
test "$R.txt" = "$sheet.csv" && (echo The same; exit 0)
Appreciate your help
Slightly tweaking your script.
#!/bin/bash
Res=$(head -n 1 "$1")
tab=$(head -n 1 "$2")
[[ $Res == $tab ]] && echo The same
Notes
"dot" is not a valid identifier (i.e. variable name) character: valid is letters, numbers and underscore, and the first character cannot be a number.
if you're doing head -1, there's no need to pipe that into tail -1
I think [[ is more readable than test, primarily because [[ forces you to have ]]
parentheses launch a subshell which is overkill for an echo statement.
the exit will only exit the subshell not your program
if you have multiple statements, use if ...; then ...; fi -- it's more readable.

How to determine if shell command didn't run or produced no output

I am executing some shell commands via a perl script and capturing output, like this,
$commandOutput = `cat /path/to/file | grep "some text"`;
I also check if the command ran successfully or not like this,
if(!$commandOutput)
{
# command not run!
}
else
{
# further processing
}
This usually works and I get the output correctly. The problem is, in some cases, the command itself does not produce any output. For instance, sometimes the text I am trying to grep will not be present in the target file, so no output will be provided as a result. In this case, my script detects this as "command not run", while its not true.
What is the correct way to differentiate between these 2 cases in perl?
you can use this to know whether the command failed or the command return nothing
$val = `cat text.txt | grep -o '[0-9]*'`;
print "command failed" if (!$?);
print "empty string" if(! length($val) );
print "val = $val";
assume that text.txt contain "123ab" from which you want to get number only.
Use $? to check if the command executed successfully: see backticks do not return any value in perl for an example.
If you're not piping to |grep you can check $? for more specific exit status,
my $commandOutput = `grep "some text" /path/to/file`;
if ($? < 0)
{
# command not run!
}
elsif ($? >> 8 > 1)
{
# file not found
}
else
{
# further processing
}

Insert Header Row using sed

I need to run a bash script via cron to update a file.
The file is a .DAT (similar to csv) and contains pipe separated values.
I need to insert a header row at the top.
Here's what I have so far:
#!/bin/bash
# Grab the file, make a backup and insert the new line
sed -i.bak 1i"red|blue|green|orange|yellow" thefilename.dat
Exit
But how can I save the file as a different file name so that it always takes fileA, edits it and then saves it as fileB
do you really rename the old one to xxx.bak or can you just save a new copy?
either way, just use redirection.
sed 1i"red|blue|green|orange|yellow" thefilename.dat > newfile.dat
or if you want the .bak as well
sed 1i"red|blue|green|orange|yellow" thefilename.dat > newfile.dat \
&& mv thefilename.dat thefilename.dat.bak`
which would create your new file and then, only if the sed completed sucessfully, rename the orig file.
In case anyone finds it useful, here is what I ended up doing....
Grab the original file, convert it to the desired file type, whilst inserting a new header row and making a log of this.
#!/bin/bash -l
####################################
#
# This script inserts a header row in the file $DAT and resaves the file in a different format
#
####################################
#CONFIG
LOGFILE="$HOME/bash-convert/log-$( date '+%b-%d-%y' ).log"
HOME="/home/rootname"
# grab original file
WKDIR="$HOME/public_html/folder1"
# new location to save
NEWDIR="$HOME/public_html/folder2"
# original file to target
DAT="$WKDIR/original.dat"
# file name and type to convert to
NEW="$NEWDIR/original-converted.csv"
####################################
# insert a new header row
HDR="header-row-1|header-row-2|header-row-2 \r"
# and update the log file
{
echo "---------------------------------------------------------" >> $LOGFILE 2>&1
echo "Timestamp: $(date "+%d-%m-%Y: %T") : Starting work" >> $LOGFILE 2>&1
touch "$LOGFILE" || { echo "Can't create logfile -- Exiting." && exit 1 ;} >>"$LOGFILE"
# check if file is writable
sudo chmod 755 -R "$NEW"
echo "Creating file \"$NEW\", and setting permissions."
touch "$NEW" || {
echo "Can't create file \"$NEW\" -- Operation failed - exiting" && exit 1 ;}
} >>"$LOGFILE" 2>&1
{
echo "Prepending line \"$HDR\" to file $NEW."
{ echo "$HDR" ; cat "$DAT" ;} > "$NEW"
{
if [ "$?" -ne "0" ]; then
echo "Something went wrong with the file conversion."
exit 1
else echo "File conversion successful. Operation complete."
fi
}
} >>"$LOGFILE" 2>&1
exit 0
I found more clear an consistent the syntax with 'i' between the two single quotes for the pattern to 'insert'.
You can simply add a header, and save it in a different file with:
sed '1i header' file > file2
In your case:
sed '1i red|blue|green|orange|yellow' file > file2
If you wanted to save it on the same file, you'd use -i option:
sed -i '1i red|blue|green|orange|yellow' file

Perl Script return value in DOS batch file

I have a DOS batch file that calls a Perl Script file:
ssutexec.pl prog=MyProg I_CARD=MyCard O_F071=ME007 F70P=MYF70P TRIG=MYTRIG
set status=%errorlevel%
if NOT %status% == 0 (
echo *******************************************************
echo MPSBM070 JOB stopped with a RETURN CODE of %status%
echo ************** END OF JOB *****************************
goto JobEnd
)
Inside the ssutexec.pl perl script file, an error condition is executed and the script exits with exit($status):
if ($status != 0)
{
system("ssutdttm.pl SSUTEXEC \"finished processing $prog_nam (Abnormal End) on\"") ;
print "******************************************************************" ;
print " JOB STOPPED - Due to Return code of ($status)" ;
print "*****************END OF JOB***************************************" ;
system("ssutdttm.pl SSUTEXEC \"finished processing $prog_nam (Abnormal End) on\"") ;
system("ssuttmdr.pl -c -b $starttime -m \"$prog_nam\"") ;
exit($status) ;
}
I am not a perl script guy. Errorlevel isn't being triggered so I am not getting the error. How can I trap the value of the perl script exit code within my DOS batch file?
INDLUDING EDITS:
The new batch file looks like this:
#echo off
setlocal enabledelayedexpansion
if not defined run_env goto ScriptExit
echo ******************************************************************
echo * MYPROG *
echo ******************************************************************
perl ssutdttm.pl MYPROG Start -
perl ssutexec.pl prog=MyProg I_CARD=MyCard O_F071=ME007 F70P=MYF70P TRIG=MYTRIG
set status=!errorlevel!
if NOT %status% == 0 (
echo *******************************************************
echo MYPROG JOB stopped with a RETURN CODE of %status%
echo ************** END OF JOB *****************************
goto JobEnd
)
:JobEnd
if %status% == 0 (
echo *******************************************************
echo NORMAL END OF JOB - RETURN CODE of %status%
echo ******** NORMAL END OF JOB ****************************
) ELSE (
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
echo ABNORMAL END OF JOB - RETURN CODE of %status%
echo !!!!!! ABNORMAL END OF JOB !!!!!!!!!!!!!!!!!!!!!!!!!!!!
)
ssutdttm.pl MYPROG end -
exit /b %status%
::
:ScriptExit
echo run_env: %run_env%
Working with batch files can really be a pain (DOS batch files make bash scripts look wonderful, and bash stinks!). The problem could be cropping up from the way batch files handle variable expansion. Here's something to try:
Add the following line to the top of your batch script (I usually put it at the top, just under my #echo off line): setlocal enabledelayedexpansion
Change all %ERRORLEVEL% references to !ERRORLEVEL! instead (exclamation marks instead of percent signs).
These changes will have the effect of causing variables to get expanded at execution time, rather than at parse-time. I've seen the %ERRORLEVEL% value get mangled when not using the delayed expansion option. Read this EnableDelayedExpansion information page for more.
I think you should be calling perl.exe with the script as an argument:
perl ssutexec.pl prog=MyProg ...
In my tests, if I have just the script name, I get prompted for what I want to use to open the test.pl file. That means perl.exe is not executing my Perl code.
Your file associations could likely be there, but your script could still be failing because of the nuances of Windows.
I tested with my two very simple scripts:
test.bat
#ECHO OFF
perl test.pl
set status=%errorlevel%
if NOT %status% == 0 (
echo status was set with value of %status%
)
and test.pl
use warnings;
use strict;
my $status = 44;
exit($status)
and the expected output:
C:\Dropbox\Programming\Perl\Learn\blah>test
status was set with value of 44