0

Im trying to automate the Establishment of symlinks depending on the memory usage of a machine, for this i want to first check what directory under my main directory is using the most Memory, for this i am using this command

cd /directory && du -h 2>/dev/null | awk '{ if ($1 ~ /G/) {print $0}}' | grep './' | awk -F '.' '{print $3}' This works perfect over a ssh connection , but when i try to put it in a script under expect i get the error:

{ if ( ~ /G/) {print myscriptname}}
       ^ parse error
{ if ( ~ /G/) {print myscriptname}}
            ^ parse error

What i find most wierd about this is that somehow the command is trying to use my actual script´s file name as an argument even tough i am running the command trough a ssh connection.

My complete code is

#!/bin/bash
expect <<-EOF
set timeout 5
spawn ssh -oPort=22 user@ip
expect "*password" { send "password\r" }
expect "*#" { send "cd /directory && du  -h 2>/dev/null | awk '{ if ($1 ~ /G/)  {print $0}}' | grep './' | awk -F '.' '{print $3}'\r" }
expect "*#" { send "exit\r" }
EOF
Letho123
  • 99
  • 1
  • 2
  • 9
  • or escaped like `\$1` and `\$0`? – Ed Morton Jul 03 '19 at 11:04
  • Possible duplicate of [How to use SSH to run a shell script on a remote machine?](https://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-a-shell-script-on-a-remote-machine) – Wiktor Stribiżew Jul 03 '19 at 11:07
  • The code wasn't complete, i have updated it – Letho123 Jul 03 '19 at 11:15
  • I am not trying to run the script on the remote machine, i am running it on my machine , and the script makes my machine connect to the remote one – Letho123 Jul 03 '19 at 11:16
  • Why are you calling `ssh` if not to make your machine connect to the remote one? In any case, did you try escaping the `$`s in the awk command as I suggested? – Ed Morton Jul 03 '19 at 11:34
  • yes i did, i now get this error ``` cant read "0" : no such variable while executing mycommand from within mycommand – Letho123 Jul 03 '19 at 11:42

1 Answers1

1

It is due to the double-quoted argument to send -- Tcl will expand any $variables in a double-quoted string.

You might want to change

expect "*#" { send "cd /directory && du  -h 2>/dev/null | awk '{ if ($1 ~ /G/)  {print $0}}' | grep './' | awk -F '.' '{print $3}'\r" }

to this, using braces to prevent variable expansion

expect "*#" { 
    send {cd /directory && du  -h 2>/dev/null | awk '$1 ~ /G/ && /.\// {print $0}' | awk -F '.' '{print $3}'}
    send "\r"
}

Ah, yes I see the main problem: your expect code is in a shell heredoc, and that is subject to variable expansion. That happens before expect is even launched.

The secret sauce here is to tell the shell to single-quote the entire here document:

expect << 'EOF'
...
EOF

Now, the $1 and $0 will be left for awk to have.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • when i try this i get a parse error on the ~ , and the $0 variable expansion becomes my script´s file name and the $3 becomes blank – Letho123 Jul 03 '19 at 14:54