3

I have a shell script with different methods.The script is

    status(){
    PID=$(ps -ef | grep jmeter_script.sh|grep -v grep|awk '{print $2}')
    }

    start(){
    shift
    if [ "$#" -ne 2 ]; then
            exit 1;
    fi
    jmeter.sh -n -t "$1"  -l "$2"
    }

    stop(){
        while true; do
            read -p "Do you really want to stop?" yn
            case $yn in
                [Yy]* ) ps -ef | grep jmeter | grep -v grep | awk '{print $2}'|xargs kill; break;;
                [Nn]* ) exit;;
                * ) echo "Please answer yes or no.";;
            esac
view(){
#some code
}

    ####Main
    while [ "$1" != "" ]; do
    case "$1" in
            start )
                start
                ;;

            stop)
                stop
                ;;

            status)
                status
                ;;
            view)
                view
                ;;
            *)
                echo $"Usage: $0 {start|stop|status|view}"
                exit 1
            esac
        shift
    done

When I try to run the script using ./jmeter_script.sh start abc.jmx log.jtl I get an error saying ./jmeter_script.sh: 19: shift: can't shift that many and then exit. I am running my script on ubuntu server. I have tried to resolve this but I ddin't find any proper link for this error. Someone please help.

user6348718
  • 1,355
  • 5
  • 21
  • 28
  • You can't shift by more than `$#`. When `$#` is 0 (as in the invocation of `start`), you can't use `shift` at all. Inside a function, `"$@"` etc are the arguments to the function call, not to the script as a whole. – Jonathan Leffler Jul 06 '16 at 04:57
  • @JonathanLeffler How do I fix that? How can I change the `if condition` in the `start()` method? or How can I change the `start()` method so that it should take the `command line arguments`. – user6348718 Jul 06 '16 at 05:06
  • @Cyrus I didn't get what you said. Can you please explain where I went wrong – user6348718 Jul 06 '16 at 05:07
  • 1
    You probably don't; you call `start arg1 arg2 arg3` so that you can shift `arg1` out of the way and then use `$1` and `$2`. Of course, there's the question of why you pass the original `$1` (`arg1` in my outline call) if you're only going to ignore it — but you can probably figure that out for yourself. – Jonathan Leffler Jul 06 '16 at 05:08
  • @user6348718: I was wrong. – Cyrus Jul 06 '16 at 05:59
  • @JonathanLeffler I am new to shell scripting. I have tried to resolve it but I didn't understand. Can you please help? – user6348718 Jul 06 '16 at 11:35
  • Your `start` function runs: `jmeter.sh -n -t "$1" -l "$2"`. That means that you need to execute `start something what-goes-in-dollar-1 what-goes-in-dollar-2`. There's no indication whatsoever of how this script as a whole might be intended to be used. Maybe you run `your-script start 1000 20` and your intention is that it should run `jmeter.sh -n -t "1000" -l "20"`? You've not said, so we can't tell for sure. It also seems like you might be able to run `your-script stop view status start 1000 20 stop` and maybe you'd be stopping, viewing, statusing, starting and stopping. – Jonathan Leffler Jul 06 '16 at 12:46
  • The $# and the positional parameters are scoped to the function. You're calling start with no arguments so $# is 0. Try calling `start "$@"` instead. – Devon_C_Miller Jul 06 '16 at 18:22
  • BTW, note that parsing `ps` output is generally a serious code smell. On modern Ubuntu you should be using `systemctl` to start, stop, check the status of, and otherwise manage services. – Charles Duffy Apr 26 '23 at 21:19

2 Answers2

1

Those are functions, not methods. Don't go overboard applying OOD terminology where it doesn't begin to apply.

The best way to avoid shift errors is not to shift when you have run out of arguments. Check the value of $# BEFORE you shift.

It would be easier to parse your ps -ef output if you don't specify lots of flags. All you need is PID and PNAME.

1

A safe shift way: shift $(( 3 > $# ? $# : 3)) In this case i try to shift 3 positions, if the count was les of that, I just shift the max.