1

Hello I am creating a script for our job that will pull the files from remote server.

  1. The user will input the file names
  2. And then using ssh command I will list the file in order for the user to check it's size first before pulling.
  3. If the user's answer=y then it will proceed on the sftp.

My problem is when performing the ssh command it will ask for a password and will ask again when doing the sftp.

I can't use sshpass as it is blocked by the admin.

#!/bin/bash

read -p "UserID: " UserID
read -p "Error file: " file1
read -p "Log file: " file2

ssh $UserID@127.0.0.1 "ls -ltr /logs/$file1 && ls -ltr /logs/$file2"
read -p "Please check the file size, do you want to proceed? (y/n): " choice

if [[ "$choice" == "y" ]]
then
sftp $UserID@127.0.0.1 << EOF
  get /logs/$file1 /home/
  get /logs/$file2 /home/
EOF
else
    echo "Exiting..."
        exit
fi

I tried using sshpass to store the password but it is blocked (permission denied) so I am looking for alternatives.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • 5
    You could look into key-based ssh, which doesn't use passwords but asymmetric keys. See [ssh-keygen](https://linux.die.net/man/1/ssh-keygen). – Robert Aug 03 '23 at 23:38
  • Another option could be [expect](https://linux.die.net/man/1/expect) but I'd consider this a hack, especially compared to key-based ssh. Might be your only option if you cannot talk your admin into ssh keys, though. – Robert Aug 03 '23 at 23:46
  • A full fledged SFTP Perl client as [Net::SFTP::Foreign](https://metacpan.org/pod/Net::SFTP::Foreign) allows one to do all those operations with a single connection quite easily. – salva Aug 22 '23 at 08:54

1 Answers1

0

Robert's comment is worth repeating:

You could look into key-based ssh, which doesn't use passwords but asymmetric keys. See ssh-keygen. – Robert

with a keyfile you could just do

read -p "UserID: " UserID
read -p "Key file location (~/.ssh/id_rsa): " keyfile
if [[ -z "$keyfile" ]]
then
    keyfile=~/.ssh/id_rsa
fi
(...)
ssh -i "$keyfile" $UserID@127.0.0.1 "ls -ltr /logs/$file1 && ls -ltr /logs/$file2"
read -p "Please check the file size, do you want to proceed? (y/n): " choice

if [[ "$choice" == "y" ]]
then
sftp -o IdentityFile="$keyfile" $UserID@127.0.0.1 << EOF
(...)

otherwise.. you're quickly approaching the complexity where using bash no longer makes sense, and you should consider upgrading to a better scripting language like PHP, Python, or Perl.

For example in PHP it would look something like

#!/usr/bin/env php
<?php
declare(strict_types=1);
function stdinQuestion(string $question): string
{
    echo $question;
    return substr(fgets(STDIN), 0, -strlen(PHP_EOL));
}
$UserID = stdinQuestion("UserID: ");
exec("stty -echo");
$Password = stdinQuestion("Password: ");
exec("stty echo");
echo PHP_EOL;
$ErrorFile = stdinQuestion("Error file: ");
$LogFile = stdinQuestion("Log file: ");
$ssh = ssh2_connect('127.0.0.1', 22);
if(!ssh2_auth_password($ssh, $UserID, $Password)) {
    die('Login Failed');
}
$command = "ls -ltr " . escapeshellarg("/logs/$ErrorFile"). " && ls -ltr " . escapeshellarg("/logs/$LogFile");
$stream = ssh2_exec($ssh, $command);
stream_set_blocking($stream, true);
$stream_out = stream_get_contents($stream);
echo $stream_out;
$proceed = stdinQuestion("Please check the file size, do you want to proceed? (y/n): ");
if ($proceed !== "y") {
    echo "Exiting...\n";
    exit();
}
ssh2_scp_recv($ssh, "/logs/$ErrorFile", "/home/$ErrorFile");
ssh2_scp_recv($ssh, "/logs/$LogFile", "/home/$LogFile");
hanshenrik
  • 19,904
  • 4
  • 43
  • 89