Need help debugging remote-update script (Bash)

Hey there,
I am currently working on a script that does an update via SSH on an remote PC.

The idea is that the host pc sends a command to create a script to the pc I want to update.
Then the pc runs the script and deletes the script afterwards.

The last thing I want to achive is that all this happenes without asking for a password.

I think I got the hardest part done but there is an error I have no idea how to fix.

This is the script:

#!/bin/bash

path=$(find -iname update.sh)

read -p "Enter IP-Adress: " ip

read -p "Enter user number (e.g. 01): " user

select connect in Certificate Update Connection

do

case $connect in

"Certificate")

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa isatlab-cli$user@$ip

;;

"Update")

ssh isatlab-cli$user@$ip '

cat > update.sh << EQF

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

select action in Kernel System Reboot CampusIT ISAT-Lab

do

case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

*)

echo "Invalid entry."

break

;;

esac

done

EQF

'

ssh isatlab-cli$user@$ip 'chmod +x update.sh'

ssh isatlab-cli$user@$ip './update.sh'

ssh isatlab-cli$user@$ip 'rm update.sh'

;;

"Connection")

ssh isatlab-cli$user@$ip

;;

*)

echo "Invalid entry"

break

;;

esac

done

This is the error:

./update.sh: line 9: syntax error near unexpected token `"Kernel"'
./update.sh: line 9: `"Kernel")'

Note that line 9 in update.sh is line 28 in the orginal script.

I hope someone can help me and explain what I am doing wrong.

Thanks in advanced!

Just don't understand why not having the script (update.sh) itself on your host and copy it to your pc you want to update?

Why to have it in this script and "create it" on the other pic via cat?

Because I dont want to have two scripts on the PC for one to work.

I would like to use this on multiple PCs and the its better to have just one file.

Should those be EQF? Did you mean EOF ?
...eh.. I guess it doesnt matter .. but yes it seems the issue is there.

But it's easier to read and debug a script itself alone..
There is already enough problem with quotes and double quotes and variable substitution in a normal script.. then to complicate it by putting this in a an other script.. just my opinion..

Okay I tried it with EOF but this didnt fix the problem. It is still the same error.

But you are right it should be EOF

Try with using 'EOF' in the first instance

and maybe better version of cat ..

cat <<EOF > update.sh

or

cat <<'EOF' > update.sh

Both versions doesnt solve the problem :frowning:

But thanks

Okay thanks form the help so far.

I just checked the script on the client pc and its correct.

So the problem is this line:

ssh isatlab-cli$user@$ip './update.sh'

Is there a better way to execute a script via ssh?

Best case would be if I could execute it with sudo without it asking me for the password.

maybe try by

exec ./update.sh
sh ./update.sh
bash ./update.sh

but .. I would also mention you can dynamically create the scrip locally, feed it to the remote and delete it instead of creating it on the remote.

Something like this:

#!/bin/bash

path=$(find . -iname update.sh)

read -p "Enter IP-Adress: " ip

read -p "Enter user number (e.g. 01): " user

select connect in Certificate Update Connection

do

case $connect in

"Certificate")

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa isatlab-cli"$user"@"$ip"

;;

"Update")

cat <<'EOF' > ./update.sh

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

select action in Kernel System Reboot CampusIT ISAT-Lab

do

case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

*)

echo "Invalid entry."

break

;;

esac

done

EOF

chmod +x ./update.sh

ssh isatlab-cli"$user"@"$ip" 'bash -s' < ./update.sh

rm ./update.sh

;;

"Connection")

ssh isatlab-cli"$user"@"$ip"

;;

*)

echo "Invalid entry"

break

;;

esac

done

Okay now the error is gone.

But there is an other problem:
After executing the remote update script and giving me the update selection bash instantly prompts the first selection.

So I need a way to let de programm pause after removing the update.sh file so that I can choose from the sewcond selection.

I tried adding a break after the remove line but that just ends the whole script.

Sorry .. I am not sure I follow.
Did you use bash or similar .. or did you use the revised script I posted ?
(what does it look like now?)

I used your version of the script.

This is what happenes:

Enter IP-Adress: <ip>
Enter user number (e.g. 01): 01
1) Certificate
2) Update
3) Connection
#? 2

1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
#? 1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
#? #? 

Two things went wrong:

  1. The second selection
1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
#?  

is displayed two times.

  1. After the second selection is displayed bash want an other input for the first selection.
1) Certificate
2) Update
3) Connection

This is why the last line looks like this:

#? #? 

The first #? is from the second selection (which I want) the second #? is from the first selection (wich I dont want).

I tried adding a break statement after:

rm ./update.sh

But this just closes the script with no action.

#!/bin/bash

path=$(find . -iname update.sh)

read -p "Enter IP-Adress: " ip

read -p "Enter user number (e.g. 01): " user

PS3='cscs says hello. make your choice: '

bigoptions=("Certificate" "Update" "Connection" "Quit")

select connect in "${bigoptions[@]}"

do

    case $connect in

"Certificate")

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa isatlab-cli"$user"@"$ip"

;;

"Update")

cat <<'EOF' > ./update.sh

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

PS3='cscs says hello. make your choice: '

liloptions=("Kernel" "System" "Reboot" "CampusIT" "ISAT-Lab" "Quit")

select action in "${liloptions[@]}"

do
    case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

"Quit")

break

;;

*)

echo "Invalid entry."

;;

esac

done

EOF

chmod +x ./update.sh

ssh isatlab-cli"$user"@"$ip" 'bash -s' < ./update.sh

rm ./update.sh

;;

"Connection")

ssh isatlab-cli"$user"@"$ip"

;;

"Quit")

break

;;

*)

echo "Invalid entry"

;;

esac

done

excuse the edit. goofed.

Now the output looks like this:

1) Certificate
2) Update
3) Connection
4) Quit
cscs says hello. make your choice: 2

1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
6) Quit
cscs says hello. make your choice: 1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
6) Quit
cscs says hello. make your choice: cscs says hello. make your choice:

(just double-checking you got the edited version .. looks like you did)
so there is something funny about that second script being sourced..

I mean when I execute this script:

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

PS3='cscs says hello. make your choice: '

liloptions=("Kernel" "System" "Reboot" "CampusIT" "ISAT-Lab" "Quit")

select action in "${liloptions[@]}"

do
    case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

"Quit")

break

;;

*)

echo "Invalid entry."

;;

esac

done

it works just fine.

And this is the script we ere creating.

I am so confused xD

#!/bin/bash

path=$(find . -iname update.sh)

read -p "Enter IP-Adress: " ip

read -p "Enter user number (e.g. 01): " user

PS3='Big script selection: '

bigoptions=("Certificate" "Update" "Connection" "Quit")

select connect in "${bigoptions[@]}"

do

    case $connect in

"Certificate")

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa isatlab-cli"$user"@"$ip"

;;

"Update")

cat <<'EOF' > ./update.sh

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

PS3='Lil script selection: '

liloptions=("Kernel" "System" "Reboot" "CampusIT" "ISAT-Lab" "Quit")

select action in "${liloptions[@]}"

do
    case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

"Quit")

break

;;

*)

echo "Invalid entry."

;;

esac

done

EOF

chmod +x ./update.sh

ssh isatlab-cli"$user"@"$ip" 'bash -ls' < ./update.sh

rm ./update.sh

;;

"Connection")

ssh isatlab-cli"$user"@"$ip"

;;

"Quit")

break

;;

*)

echo "Invalid entry"

;;

esac

done
1) Certificate
2) Update
3) Connection
4) Quit
Big script selection: 2
1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
6) Quit
Lil script selection: 1) Kernel
2) System
3) Reboot
4) CampusIT
5) ISAT-Lab
6) Quit
Lil script selection: 
Big script selection:     

Maybe a different approach with cat ..

#!/bin/bash

path=$(find . -iname update.sh)

read -p "Enter IP-Adress: " ip

read -p "Enter user number (e.g. 01): " user

PS3='Big script selection: '

bigoptions=("Certificate" "Update" "Connection" "Quit")

select connect in "${bigoptions[@]}"

do

    case $connect in

"Certificate")

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa isatlab-cli"$user"@"$ip"

;;

"Update")

cat <<'EOF' > ./update.sh

#!/bin/bash

campusIT=enp42s0

isatLab=enp43s0

currentKernel=linux55

PS3='Lil script selection: '

liloptions=("Kernel" "System" "Reboot" "CampusIT" "ISAT-Lab" "Quit")

select action in "${liloptions[@]}"

do
    case $action in

"Kernel")

echo "Updating Kernel"

sudo mhwd-kernel -i $currentKernel rmc

;;

"System")

echo "Updating System"

sudo pacman -Syyu

echo "Updating complete!"

;;

"Reboot")

rm ./tempUpdate.sh

sudo systemctl reboot

;;

"CampusIT")

sudo ip link set $campusIT up

sudo ip link set $isatLab down

echo "Network interface now running."

;;

"ISAT-Lab")

sudo ip link set $campusIT down

sudo ip link set $isatLab up

echo "Network interface shut down."

;;

"Quit")

break

;;

*)

echo "Invalid entry."

;;

esac

done

EOF

chmod +x ./update.sh

ssh isatlab-cli"$user"@"$ip" 'bash -ls' < cat ./update.sh

rm ./update.sh

;;

"Connection")

ssh isatlab-cli"$user"@"$ip"

;;

"Quit")

break

;;

*)

echo "Invalid entry"

;;

esac

done

Forum kindly sponsored by