boolean expression in sh script - sh

I have this simple script, which wouldn't run because of the line with if [ ... ]
Could anyone tell me what is wrong with this?
#! /bin/sh
if [ $# -ne 2 AND $# -ne 3 ]
then
echo "Usage $0 <input> <output> [<comment>]"
exit 1
fi;
Thanks!

Try the following :
#! /bin/sh
if [ $# -ne 2 -a $# -ne 3 ]
then
echo >&2 "Usage $0 <input> <output> [<comment>]"
exit 1
fi
Or :
#! /bin/sh
if [ $# -ne 2 ] && [ $# -ne 3 ]
then
echo >&2 "Usage $0 <input> <output> [<comment>]"
exit 1
fi
If you'd like to use bash :
#! /bin/bash
if [[ $# -ne 2 && $# -ne 3 ]]
then
echo >&2 "Usage $0 <input> <output> [<comment>]"
exit 1
fi

Related

How do I fix 'command not found' that popped out when I tried 'egrep' from a variable?

I wanted to make a program that searches all the lines that contains all the factors given, from a file mydata. I tried to egrep first factor from mydata and save it in a variable a. Then, I tried to egrep the next factor from a and save the result to a again until I egrep all the factors. But when I executed the program, it said
"command not found" in line 14.
if [ $# -eq 0 ]
then
echo -e "Usage: phoneA searchfor [...searchfor]\n(You didn't tell me what you want to search for.)"
else
a=""
for i in $*
do
if [ -z "$a" ]
then
a=$(egrep "$i" mydata)
else
a=$("$a" | egrep "$i")
fi
done
awk -f display.awk "$a"
fi
I expected all the lines including all the factors outputted on the screen in the pattern that I made in display.awk.
$a contains data, not a command. You need to write that data to the pipe.
if [ $# -eq 0 ]
then
printf '%s\n' "Usage: phoneA searchfor [...searchfor]" "(You didn't tell me what you want to search for.)" >&2
exit 1
fi
a=""
for i in "$#"; do
if [ -z "$a" ]; then
a=$(egrep "$i" mydata)
else
a=$(printf '%s' "$a" | egrep "$i")
fi
done
awk -f display.awk "$a"

Remove old Elasticsearch indexes if ELK is installed in docker container using curl

ELK is installed on docker . Due to old logs and indexes server hard disk capacity gets full resulting crash of ELK container.
Run below shell script on docker shell on which elk is installed
#!/bin/bash
DAYSAGO=date --date="200 days ago" +%Y%m%d
ALLLINES=/usr/bin/curl -s -XGET http://127.0.0.1:9200/_cat/indices?v | egrep logstash
echo
echo "THIS IS WHAT SHOULD BE DELETED FOR ELK:"
echo
echo "$ALLLINES" | while read LINE
do
FORMATEDLINE=echo $LINE | awk '{ print $3 }' | awk -F'-' '{ print $2 }' | sed 's/\.//g'
if [ "$FORMATEDLINE" -lt "$DAYSAGO" ]
then
TODELETE=echo $LINE | awk '{ print $3 }'
echo "http://127.0.0.1:9200/$TODELETE"
fi
done
echo
echo -n "if this make sence, Y to continue N to exit [Y/N]:"
read INPUT
if [ "$INPUT" == "Y" ] || [ "$INPUT" == "y" ] || [ "$INPUT" == "yes" ] || [ "$INPUT" == "YES" ]
then
echo "$ALLLINES" | while read LINE
do
FORMATEDLINE=echo $LINE | awk '{ print $3 }' | awk -F'-' '{ print $2 }' | sed 's/\.//g'
if [ "$FORMATEDLINE" -lt "$DAYSAGO" ]
then
TODELETE=echo $LINE | awk '{ print $3 }'
/usr/bin/curl -XDELETE http://127.0.0.1:9200/$TODELETE
sleep 1
fi
done
else
echo SCRIPT CLOSED BY USER, BYE ...
echo
exit
fi

PID increments automatically

I'm writing a init-script for a microservice and have the problem, that the PID of the process, that the program gives out (via echo) is not the process ID the process is having. The code:
#!/bin/bash
### BEGIN INIT INFO
# Provides: temp
# Description: temp
# required-start: $local_fs $remote_fs $network $syslog
# required-stop: $local_fs $remote_fs $network $syslog
# default-start: 3 5
# default-stop: 0 1 2 6
# chkconfig: 35 99 1
# description: Microservice init-script
### END INIT INFO
START_SCRIPT=${applicationDirectory}/script/start.sh
STOP_SCRIPT=${applicationDirectory}/script/stop.sh
PID_FILE=${runDirectory}/${microserviceName}_${environment}_${servicePort}
# ***********************************************
# ***********************************************
DAEMON=$START_SCRIPT
# colors
red='\e[0;31m'
green='\e[0;32m'
yellow='\e[0;33m'
reset='\e[0m'
echoRed() { echo -e "${red}$1${reset}"; }
echoGreen() { echo -e "${green}$1${reset}"; }
echoYellow() { echo -e "${yellow}$1${reset}"; }
start() {
#PID=`bash ${START_SCRIPT} > /dev/null 2>&1 & echo $!`
PID=`$DAEMON $ARGS > /dev/null 2>&1 & echo $!`
}
stop() {
STOP_SCRIPT $1
}
case "$1" in
start)
if [ -f $PID_FILE ]; then
PID=`cat $PID_FILE`
if [ -z "`echo kill -0 ${PID}`" ]; then
echoYellow "Microservice is already running [$PID]."
exit 1
else
rm -f $PID_FILE
fi
fi
start
if [ -z $PID ]; then
echoRed "Failed starting microservice."
exit 3
else
echo $PID > $PID_FILE
echoGreen "Microservice successfully started [$PID]."
exit 0
fi
;;
status)
if [ -f $PID_FILE ]; then
PID=`cat $PID_FILE`
if [ ! -z "`echo kill -0 ${PID}`" ]; then
echoRed "Microservice is not running (process dead but pidfile exists)."
exit 1
else
echoGreen "Microservice is running [$PID]."
exit 0
fi
else
echoRed "Microservice is not running."
exit 3
fi
;;
stop)
if [ -f $PID_FILE ]; then
PID=`cat $PID_FILE`
if [ ! -z "`echo kill -0 ${PID}`" ]; then
echoRed "Microservice is not running (process dead but pidfile exists)."
exit 1
else
PID=`cat $PID_FILE`
stop $PID
echoGreen "Microservice successfully stopped [$PID]."
rm -f $PID_FILE
exit 0
fi
else
echoRed "Microservice is not running (pid not found)."
exit 3
fi
;;
*)
echo "Usage: $0 {status|start|stop}"
exit 1
esac
Now, the program gives for example 2505 as PID. But when I use
ps aux | grep trans | grep -v grep
It outputs a number, that is the previously outputted number +1.
Can anyone give a guess? Any help is appreciated!
Your PID variable gets the pid of the shell that executes start.sh. The actual program executed by the script gets a different pid.

Trying to clone a ksh function with little modification with a one liner perl

I've a short ksh script that is often generated automatically. However, it's missing some stuff and I want to be able to "fix it" like I want by running a simple 1 liner perl to sed it.
Let say that the ksh contains the following function:
foo()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop param2
fi
#...
}
and what I really want looks like this
foo_force()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop -f param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop -f param2
fi
#...
}
foo()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop param2
fi
#...
foo_force
}
So far I've been able to get something "close", ie 2 perl commands, which would be ok with me. However, the second command only replace the last stop by a -f stop... which is not what I'm looking for.
/usr/bin/perl -i -pe "BEGIN{undef $/;}; s/^(foo)(\(\)\n{.*\n)}/\1_force\2}\n\n\1\2\t\1_force\n}/gms" /tmp/foo.ksh
/usr/bin/perl -i -pe "BEGIN{undef $/;}; s/^(foo\(\)\n{.* stop)( .*\n})/\1 -f\2/gms" /tmp/foo.ksh
This might work for you (GNU sed):
sed -i '/^foo()/{:a;$!N;/\n}/!ba;h;s/^foo/&_force/;s/stop /&-f /g;s/$/\n/p;g;s/\n}/\n\n foo_force&/}' /file
Using perl
perl -0777 -i -pe '
s{(^foo\(\).*?\n\})}{
my $foo = my $force = $1;
$foo =~ s/\}$/ foo_force()\n\}/;
$force =~ s/^foo\K/_force/;
$force =~ s/ stop \K/-f /g;
"$foo\n$force"
}mse;
' /tmp/foo.ksh

Resolve name by inode in current direcory

How can I resolve the name by the given inode in the current directory in the following script that prints all filenames of symlinks pointing to a specified file that is passed as an argument to the script. The list should be sorted by ctime.
#!/usr/bin/ksh
IFS="`printf '\n\t'`"
USAGE="usage: symlink.sh <file>"
get_ctime() {
perl -se 'use File::stat; $file=lstat($filename); print $file->ctime' -- -filename="$1"
}
stat_inode() {
perl -se 'use File::stat; $file=stat($filename); if (defined $file) { print $file->ino; }' -- -filename="$1"
}
lstat_inode() {
perl -se 'use File::stat; $file=lstat($filename); if (defined $file) { print $file->ino; }' -- -filename="$1"
}
if [ $# -eq 0 ]; then
echo "$USAGE"
exit 1
fi
FILE_NAME="$1"
FILE_INODE=$(stat_inode "$FILE_NAME")
if [ ! -e "$FILE_NAME" ]; then
echo "no such file \"$FILE_NAME\""
exit 1
fi
for LINK in ./* ./.[!.]* ;do
if [ -L "$LINK" ]; then
TARGET_INODE=$(stat_inode "$LINK")
if [ ! -z "$TARGET_INODE" ]; then
if [ "$FILE_INODE" -eq "$TARGET_INODE" ]; then
echo $(get_ctime "$LINK") $(lstat_inode "$LINK");
fi
fi
fi
done | sort -nk1 | awk '{print $2}'
Basically, I'd like to pipe awk to some kind of lookup function like this: | awk ' ' | lookup
I'd really appreciate if someone suggested a more elegant way to accomplish the task.
OS: SunOS 5.10
Shell: KSH
Something like this?
$ find . -maxdepth 1 -inum 2883399
./.jshintrc
$
or:
$ echo 2883399 | xargs -IX find . -maxdepth 1 -inum X
./.jshintrc
$