Search code examples
linuxbashfunctionpowershellsshpass

sshpass will not run provided command on Ubuntu remote host when script is sourced, but does run on windows and if run within the same script


I've searched on here for a bit and can't find someone who is going through this issue.

I have a tool/script I am building that uses sshpass to login to a remote host and pull logs, restart, etc... If I run the function within the main script it runs with no issues. If I source the script with the function, then it runs well if its accessing a windows IOT Core remote host, but will not execute commands if the remote host is linux.

My device:
Macbook Pro 2018
macOs Mojave 10.14.2

Application
Terminal

Here's what works:

mainFile.sh:

#!/bin/bash

function pullWindowsLog {
    sshpass -p 'password' ssh [email protected] <<EOF
powershell.exe
Get-Content  c:\Path\To\Log\Log.log -tail 10
EOF
}

function pullLinuxLog {
    sshpass -p 'password' ssh [email protected] <<EOF
echo 'password' | sudo -S docker logs --tail 10 container
EOF
}



function mainMenu {
    local PS3="What would you like to do?"
    local options=("Pull Windows Log" "Pull Linux Logs" "Quit")
    select opt in "${options[@]}"
    do
        case $opt in
            "Pull Windows Log")
                pullWindowsLog
                ;;
            "Pull Linux Logs")
                pullLinuxLog
                ;;
            "Quit")
                clear
                break
                ;;
            *) echo "\ninvalid option \n";;
        esac
    done
}

mainMenu

Output:

1) Pull Windows Log
2) Pull Linux Logs
3) Quit


What would you like to do?1 # <- user input

Pseudo-terminal will not be allocated because stdin is not a terminal.
Microsoft Windows [Version 0.0.0.0]
Copyright (c) Microsoft Corporation. All rights reserved.

user@WindowsDevice C:\Data\Users\User>powershell.exe
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Data\Users\User> Get-Content  c:\Path\To\Log\Log.log -tail 10
00:00:00.0000 Log line 1
00:00:00.0000 Log line 2
00:00:00.0000 Log line 3
00:00:00.0000 Log line 4
00:00:00.0000 Log line 5
00:00:00.0000 Log line 6
00:00:00.0000 Log line 7
00:00:00.0000 Log line 8
00:00:00.0000 Log line 9
00:00:00.0000 Log line 10

PS C:\Data\Users\User>

What would you like to do?2 # <- user input

Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 00.00.00 

  System information as of Day Mon  0 00:00:00 xxx Year

  System load:  0.00               Users logged in:             0
  Usage of /:   00.0% of 00.00GB   IP address for eth0:         00.00.00.00
  Memory usage: 00%                IP address for eth1:         00.00.00.00
  Swap usage:   0%                 IP address for eth2:         00.00.00.00
  Processes:    000

0 packages can be updated.
0 updates are security updates.

[sudo] password for user:

00:00:00.0000 Log line 1
00:00:00.0000 Log line 2
00:00:00.0000 Log line 3
00:00:00.0000 Log line 4
00:00:00.0000 Log line 5
00:00:00.0000 Log line 6
00:00:00.0000 Log line 7
00:00:00.0000 Log line 8
00:00:00.0000 Log line 9
00:00:00.0000 Log line 10

What would you like to do?3 # <- user input

What I would prefer, but is not working:

MainFile.sh:

#!/bin/bash

source pullWindowsLog.sh
source pullLinuxLog.sh

function mainMenu {
    local PS3="What would you like to do?"
    local options=("Pull Windows Log" "Pull Linux Logs" "Quit")
    select opt in "${options[@]}"
    do
        case $opt in
            "Pull Windows Log")
                pullWindowsLog
                ;;
            "Pull Linux Logs")
                pullLinuxLog
                ;;
            "Quit")
                clear
                break
                ;;
            *) echo "\ninvalid option \n";;
        esac
    done
}

mainMenu

pullWindowsLog.sh:

#!/bin/bash

function pullWindowsLog {
    sshpass -p 'password' ssh [email protected] <<EOF
powershell.exe
Get-Content  c:\Path\To\Log\Log.log -tail 10
EOF
}

pullLinuxLog.sh:

#!/bin/bash

function pullLinuxLog {
    sshpass -p 'password' ssh [email protected] <<EOF
echo 'password' | sudo -S docker logs --tail 10 container
EOF
}

Output:

1) Pull Windows Log
2) Pull Linux Logs
3) Quit


What would you like to do?1 # <- user input

Pseudo-terminal will not be allocated because stdin is not a terminal.
Microsoft Windows [Version 0.0.0.0]
Copyright (c) Microsoft Corporation. All rights reserved.

user@WindowsDevice C:\Data\Users\User>powershell.exe
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Data\Users\User> Get-Content  c:\Path\To\Log\Log.log -tail 10
00:00:00.0000 Log line 1
00:00:00.0000 Log line 2
00:00:00.0000 Log line 3
00:00:00.0000 Log line 4
00:00:00.0000 Log line 5
00:00:00.0000 Log line 6
00:00:00.0000 Log line 7
00:00:00.0000 Log line 8
00:00:00.0000 Log line 9
00:00:00.0000 Log line 10

PS C:\Data\Users\User>

What would you like to do?2 # <- user input

Pseudo-terminal will not be allocated because stdin is not a terminal.

What would you like to do?3 # <- user input

For anyone concerned with security, I do not have any passwords hardcoded in the script. I just wrote it this way for the question. I am not having issues with passing variables, just how sshpass is acting when being sourced. I don't understand why there would be a difference on the remote host OS, but it is the only thing that is different. I tried running just an ls or echo and nothing. I also tried sshpass -p 'password' ssh [email protected] <command> and didnt even get a Pseudo-terminal will not be allocated because stdin is not a terminal.. As you can see in the first output, the linux system information is loaded. This is not happening in the second output.

I understand that I could just have everything in one script, but I am hoping to expand on this tool and would rather just add a menu item when the tool is ready. Also keeping the environment clean will allow me to easily pass this on to someone else to expand.

I hope I provided enough information (probably TMI at this point) for some terminal genius to figure this out.

Thank you in advance.


Solution

  • Figured it out. I feel like I should have known this, but somehow it slipped my mind. I had to add -t -oStrictHostKeyChecking=no on sshpass. so the command should be

    sshpass -p 'password' ssh -t -oStrictHostKeyChecking=no "[email protected]" <<EOF
    echo 'password' | sudo -S docker logs --tail 10 container
    EOF
    
    

    Hopefully someone finds this and it helps them.