#!/bin/bash
host=$1
startport=$2
stopport=$3
function pingcheck
{
ping = `ping -c 1 $host | grep bytes | wc -l`
if [ $ping > 1 ]; then
echo "$host is up";
else
echo "$host is down quitting";
exit
fi
}
function portcheck
{
for ((counter=$startport; counter<=$stopport; counter++))
do
(echo > /dev/tcp/$host/$counter) > /dev/null 2>&1 && echo "$counter open"
done
}
pingcheck
portcheck
I tried testing the script by passing 127.0.0.1 1 5 to it from the terminal but all i keep getting is ping: unknown host =
127.0.0.1 is down quitting. Tried with other IP Addresses as well, I got the same output. I was following instruction from a book as I am new to shell scripting. It will be helpful if someone can tell me what I am doing wrong.
I made some comments inline:
#!/bin/bash
host=$1
startport=$2
stopport=$3
function pingcheck
{
ping=`ping -c 1 $host | grep bytes | wc -l` #Don't use spaces before and after the "="
if [ $ping -gt 1 ]; then #Don't use >, use -gt
# if [[ $ping > 1 ]]; then #Or use [[ and ]], but this won't work in all shells
echo "$host is up";
else
echo "$host is down quitting";
exit
fi
}
function portcheck
{
for ((counter=$startport; counter<=$stopport; counter++))
do
(echo > /dev/tcp/$host/$counter) > /dev/null 2>&1 && echo "$counter open"
done
}
pingcheck
portcheck
Variables in bash are always in the format:
VARNAME=VALUE
You should not put spaces in between there. VALUE could be an expression using `` or using $(). $() is usually the preferred way, because you can do $(something $(something)) and you can't do `something `something``.
The syntax of if is:
if EXPRESSION
then
something
fi
An expression is in sh always a call to an application. [ is an application usually used in ifs. You can get a really good manual of [ by doing man [. Bash has native support for [[, which isn't an application, but can do more than [.
Related
I try to do a simple script with BASH that try to ping each Arguments($1 $2 $3...etc). From now, I'm able to ping a single argument and receive the good answer but it not working properly with multiple arguments entered; like this (./Script.sh Arg1 Arg2....). Plus, the script work for a single Arguments entry but it keeps telling me that their is an error link to my line 6 just before giving the echo link to the condition.
#!/bin/bash
PING=`ping -c 1 "$#" | grep bytes | wc -l`
for ip in "$#"; do "${PING}" ;
if [[ "$PING" -gt 1 ]];then
echo "L'address ${ip} ping"
else
echo "L'adresse ${ip} ne ping pas"
fi
done
and the output is :
./bash3.sh: line 6: 2: command not found
L'address IP ping
if I add more then one address before executing it always pass by the else which is "Address unreachable"
You're setting PING to the output of the ping -c 1 "$#" | grep bytes | wc -l command when the script starts. You're not setting it to the command line so that you can execute it during the loop.
Use a function, not a variable.
You can also use the -c option to grep to return the count of matches, rather than piping to wc -l
ping_count() {
ping -c 1 "$#" | grep -c bytes
}
for ip in "$#"; do
if [[ $(ping_count "$ip") -gt 1 ]];
then echo "L'address $ip ping"
else echo "L'adresse $ip ne ping pas"
fi
done
Also, ping sets its exit status based on whether it got a response. So instead of counting matching lines, just test the result of ping.
for ip in "$#"; do
if ping -c 1 -q "$ip"
then echo "L'address $ip ping"
else echo "L'adresse $ip ne ping pas"
fi
done
#!/usr/bin/env bash
for input in "$#"
do
ping=$(ping -c 1 $# | grep bytes | wc -l)
if [ $ping -gt 1 ]; then
echo "L'address IP ping"
else
echo "L'adresse IP ne ping pas"
fi
done
have some problem with shell script.
In our office we set up only few commands, that available for devs when they are trying ssh to server. It is configured with help of .ssh/authorized_keys file and available command for user there is bash script:
#!/bin/sh
if [[ $1 == "--help" ]]; then
cat <<"EOF"
This script has the purpose to let people remote execute certain commands without logging into the system.
For this they NEED to have a homedir on this system and uploaded their RSA public key to .ssh/authorized_keys (via ssh-copy-id)
Then you can alter that file and add some commands in front of their key eg :
command="/usr/bin/dev.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
The user will do the following : ssh testuser#server tail testserver.example.com/2017/01/01/user.log
EOF
exit 0;
fi
# set global variable
set $SSH_ORIGINAL_COMMAND
# set the syslog path where the files can be found
PATH="/opt/syslog/logs"
# strip ; or any other unwanted signs out of the command, this prevents them from breaking out of the setup command
if [[ $1 != "" ]]; then
COMMAND=$1
COMMAND=${COMMAND//[;\`]/}
fi
if [[ $2 != "" ]]; then
ARGU1=$2
ARGU1=${ARGU1//[;\`]/}
fi
if [[ $3 != "" ]]; then
ARGU2=$3
ARGU2=${ARGU2//[;\`]/}
fi
if [[ $4 != "" ]]; then
ARGU3=$4
ARGU3=${ARGU3//[;\`]/}
fi
# checking for the commands
case "$COMMAND" in
less)
ARGU2=${ARGU1//\.\./}
FILE=$PATH/$ARGU1
if [ ! -f $FILE ]; then
echo "File doesn't exist"
exit 1;
fi
#echo " --------------------------------- LESS $FILE"
/usr/bin/less $FILE
;;
grep)
if [[ $ARGU2 == "" ]]; then
echo "Pls give a filename"
exit 1
fi
if [[ $ARGU1 == "" ]]; then
echo "Pls give a string to search for"
exit 1
fi
ARGU2=${ARGU2//\.\./}
FILE=$PATH/$ARGU2
/usr/bin/logger -t restricted-command -- "------- $USER Executing grep $ARGU1 \"$ARGU2\" $FILE"
if [ ! -f $FILE ]; then
echo "File doesn't exist"
/usr/bin/logger -t restricted-command -- "$USER Executing $#"
exit 1;
fi
/bin/grep $ARGU1 $FILE
;;
tail)
if [[ $ARGU1 == "" ]]; then
echo "Pls give a filename"
exit 1
fi
ARGU1=${ARGU1//\.\./}
FILE=$PATH/$ARGU1
if [ ! -f $FILE ]; then
echo "File doesn't exist"
/usr/bin/logger -t restricted-command -- "$USER Executing $# ($FILE)"
exit 1;
fi
/usr/bin/tail -f $FILE
;;
cat)
ARGU2=${ARGU1//\.\./}
FILE=$PATH/$ARGU1
if [ ! -f $FILE ]; then
echo "File doesn't exist"
exit 1;
fi
/bin/cat $FILE
;;
help)
/bin/cat <<"EOF"
# less LOGNAME (eg less testserver.example.com/YYYY/MM/DD/logfile.log)
# grep [ARGUMENT] LOGNAME
# tail LOGNAME (eg tail testserver.example.com/YYYY/MM/DD/logfile.log)
# cat LOGNAME (eg cat testserver.example.com/YYYY/MM/DD/logfile.log)
In total the command looks like this : ssh user#testserver.example.com COMMAND [ARGUMENT] LOGFILE
EOF
/usr/bin/logger -t restricted-command -- "$USER HELP requested $#"
exit 1
;;
*)
/usr/bin/logger -s -t restricted-command -- "$USER Invalid command $#"
exit 1
;;
esac
/usr/bin/logger -t restricted-command -- "$USER Executing $#"
The problem is next:
when i try to exec some command, it takes only first argument, if i do recursion in files by using {n,n1,n2} - it doesn't work:
[testuser#local ~]$ ssh testuser#syslog.server less srv1838.example.com/2017/02/10/local1.log |grep 'srv2010' | wc -l
0
[testuser#local ~]$ ssh testuser#syslog.server less srv2010.example.com/2017/02/10/local1.log |grep 'srv2010' | wc -l
11591
[testuser#local ~]$ ssh testuser#syslog.server less srv{1838,2010}.example.com/2017/02/10/local1.log |grep 'srv2010' | wc -l
0
[testuser#local ~]$ ssh testuser#syslog.server less srv{2010,1838}.example.com/2017/02/21/local1.log |grep 'srv2010' | wc -l
11591
Could someone help me, how can i parse\count command arguments to make it work?
Thank you and have a nice day!
The number of arguments for a bash script would be $#. As a quick example:
#!/bin/bash
narg=$#
typeset -i i
i=1
while [ $i -le $narg ] ; do
echo " $# $i: $1"
shift
i=$i+1
done
gives, for bash tst.sh a b {c,d}
4 1: a
3 2: b
2 3: c
1 4: d
In your script, the command to execute (cat, less, ...) gets explicitly only the second argument to the script. If you want to read all arguments, you should do something like this (note: only a hint, removed all sorts of checks etc..)
command="$1"
shift
case $command in
(grep) pattern="$1"
shift
while [ $# -gt 0 ] ; do
grep "$pattern" "$1"
shift
done
;;
esac
note: added some quotes as comment suggested, but, being only a hint, you should carefully look at quoting and your checks in your own script.
Less command working now:
case "$COMMAND" in
less)
if [[ $ARGU1 == "" ]]; then
echo "Pls give a filename"
exit 1
fi
FILES_LIST=${#:2}
FILE=(${FILES_LIST//\.\./})
for v in "${FILE[#]}";do
v=${v//[;\']/}
if [ ! -f $v ]; then
echo "File doesn't exist"
fi
/usr/bin/less $PATH/$v
done;;
tail command works too with 2 and more files, but i can't execute tail -f command on two files unfortunately.
I have 4 important services running on my machine which I want to see them all the time. I have this simple bash script running as bash profile.
echo
PROC="nginx mysql php-fpm pptpd"
for p in $PROC
do
ps cax | grep $p > /dev/null
if [ $? -eq 0 ]; then
echo -e "\e[92m$p running\e[0m"
else
echo -e "\e[101m$p IS NOT RUNNING \e[0m"
fi
done
echo
The out put of this script is:
nginx running
mysql running
php-fpm running
pptpd running
How can I make it like this?
nginx running - mysql running - php-fpm running - pptpd running
Build the status lines first into an array, and then print the array:
status=()
for p in $PROC
do
if ps cax | grep -q $p; then
status+=( " \e[92m$p running\e[0m " )
else
status+=( " \e[101m$p IS NOT RUNNING \e[0m " )
fi
done
(IFS=-; echo -e "${status[*]}")
${status[*]} expands to every element in the array joined by the first character of IFS, which I set to - earlier. Note that I used a subshell (IFS=-; echo ...), so that changing IFS doesn't affect the rest of the script.
Other notes:
ps cax | grep $p > /dev/null
if [ $? -eq 0 ]; then
Can be combined to:
if ps cax | grep -q $p; then
Which is much more concise and readable. You could also consider using pgrep instead.
Use printf or add the -n flag to echo.
POSIX Compliant Refactor without ProcTools
#!/bin/sh
showstatus() {
echo
while [ "$1" ]; do
if ps cax | grep -qF "$1"; then
msg='\e[92m%s running\e[0m'
else
msg='\e[101m%s IS NOT RUNNING \e[0m'
fi
printf "$msg" "$1"
shift
[ "$1" ] && printf ' - '
done
echo
}
showstatus nginx mysql php-fpm pptpd
POSIX Compliant Refactor with ProcTools
#!/bin/sh
showstatus() {
echo
while [ "$1" ]; do
if pkill -0 "$1"; then
msg='\e[92m%s running\e[0m'
else
msg='\e[101m%s IS NOT RUNNING \e[0m'
fi
printf "$msg" "$1"
shift
[ "$1" ] && printf ' - '
done
echo
}
showstatus nginx mysql php-fpm pptpd
I am writing a script to pass commands to a console and redirect the output to a log for analysis. This is the script I have now.
#!/bin/ksh
gg_sci(){
$GG_HOME/ggsci <<EOF > /home/org/obey.log
obey /home/org/mon.oby
EOF
}
check_st(){
status=`cat obey.log | grep -i $1 | awk '$2!=""{print $2}'`
echo $status
if [ $status -eq "RUNNING" ]
then
echo "GG process $1 is running"
exit 0
}
gg_sci
check_st test
This script works if I put the 2 functions into 2 different scripts. When I put them into one script, I get an error
ksh: 0403-057 Syntax error: `}' is not expected.
After debugging, I've determined the EOF is reading in the } that closes the function. I'm not sure what I'm doing wrong, the EOF function works correctly if that's the only thing in the script.
You're missing a fi to close your if.
Also, -eq is used to check for numeric equality, to compare strings use =:
check_st(){
status=`cat obey.log | grep -i $1 | awk '$2!=""{print $2}'`
echo "$status"
if [ "$status" = "RUNNING" ]
then
echo "GG process $1 is running"
exit 0
fi
}
I am converting my script from bash to dash... and have problem getting the return code of a function.
#!/bin/sh
check_ip() {
local netbit=`echo "$1" | awk -F\/ '{print $1}'`
local netmask=`echo "$1" | awk -F\/ '{print $2}'`
if case "$netbit" in
*[!.0-9]* | *.*.*.*.* | *..* | [!0-9]* | *[!0-9] ) false ;;
*25[6-9]* | *2[6-9][0-9]* | *[3-9][0-9][0-9]* | *[0-9][0-9][0-9][0-9]* ) false;;
*.*.*.* ) true ;;
* ) false ;;
esac; then
if [ ! -z "$netmask" ] ; then
if [ "$netmask" -ge 1 ] && [ "$netmask" -le 32 ] ; then
return 0
else
return 1
fi
else
return 0
fi
else
return 1
fi
}
# this is working without the [] thing.
if check_ip "$1" ; then
echo ok
else
echo no
fi
looked up the similar script from another machine, and it has no [] as #barmar suggested. all working now. thank you very much.
$? reads the exit status of the last command executed.
a() {
return 0;
}
b() {
return 1;
}
a;
echo $?;
b;
echo $?;
would return:
0
1
The if command chooses the then or else clauses based on the exit status of the command. You only use [ if you want to perform the tests defined in the test command; if you just want to test a specific command, you use it directly.
if check_ip "$ip"
then echo Good IP
else echo Bad IP
fi
It's also very unlikely that $! would be an appropriate parameter to your function. $! is the PID of the last background process that was started, not an IP.