impika
impika

Reputation: 135

Store output of command in sftp to variable and list

My aim is to create a shell script such that it logins and filter the list of files available and select a file to get. Here I need to run commands like in bash. My sample code is:

sshpass -p password sftp [email protected] <<EOF
cd /home/
var=$(ls -rt)
echo $var
echo "select a folder"
read folder
cd $folder
filen=&(ls -rt)
echo $filen
echo "select a file"
read name
get $name
bye
EOF

Upvotes: 0

Views: 4407

Answers (3)

Praveen Mishra
Praveen Mishra

Reputation: 151

I would suggest you to create a file with pattern of the files you want downloaded and then you can get files downloaded in one single line:

sftp_connection_string <<< $"ls -lrt"|grep -v '^sftp'|grep -f pattern_file|awk '{print $9}'|sed -e 's/^/get -P /g'|sftp_connection_string

if there are multiple definite folders to be looked into, then:

**Script version**
for fldr in folder1 folder2 folder3;do
    sftp_connection_string <<< $"ls -lrt ${fldr}/"|grep -v '^sftp'|grep -f pattern_file|awk '{print $9}'|sed -e "s/^/get -P ${fldr}/g"|sftp_connection_string
done

One-liner

for fldr in folder1 folder2 folder3;do sftp_connection_string <<< $"ls -lrt ${fldr}/"|grep -v '^sftp'|grep -f pattern_file|awk '{print $9}'|sed -e "s/^/get -P ${fldr}\//g"|sftp_connection_string;done

let me know if it works.

Upvotes: 0

dash-o
dash-o

Reputation: 14432

After some research and experimentation, found a way to create batch/interactive sessions with sftp. Posting as separate answer, as I still believe the easier way to go is with lftp (see other answer). Might be used on system without lftp

The initial exec create FD#3 - pointing to the original stdout - probably user terminal. Anything send to stdout will be executed by the sftp in the pipeline.

The pipe is required to allow both process to run concurrently. Using here doc will result in sequential execution. The sleep statement are required to allow SFTP to complete data retrieval from remote host.


exec 3>&1
(
   echo "cd /home/"
   echo "ls"
   sleep 3    # Allow time for sftp 
   echo "select a folder" >&3
   read folder
   echo "cd $folder"
   echo "ls"
   sleep 3     # Allow time for sftp
   echo "select a file" >&3
   read name
   echo "get $name"
   echo "bye"
) | sshpass -p password sftp [email protected]

Upvotes: 1

dash-o
dash-o

Reputation: 14432

The above approach will not work. Remember that the 'here document' (<<EOF ... EOF) is evaluate as input to the sftp session. Prompts will be displayed, and user input will be requested BEFORE any output (ls in this case) will be available from sftp.

Consider using lftp, which has more flexible construct. In particular, it will let you use variables, create command dynamically, etc.

lftp sftp://user@host <<EOF

cd /home
ls
echo "Select Folder"
shell 'read folder ; echo "cd $folder" >> temp-cmd'
source temp-cmd

ls
echo "Select Folder"
shell 'read file ; echo "get $file" >> temp-cmd'
source temp-cmd

EOF

In theory, you can create similar constructs with pipes and sftp (may be a co-process ?), but this is much harder.

Of course, the other alternative is to create different sftp sessions for listing, but this will be expensive/inefficient.

Upvotes: 2

Related Questions