sftp
is hard to use reliably in scripts. You could use some SFTP module of some programming languages instead. For instance with perl's Net::SFTP::Foreign
:
perl -MNet::SFTP::Foreign -le '
($host, $dir, $id) = @ARGV;
$s = Net::SFTP::Foreign->new($host, autodie => 1, fs_encoding => latin1);
print scalar @{
$s->ls($dir, names_only => 1, wanted => qr/\Q$id\E.*\.txt\z/s)
}' -- "$FTP_UNAME@$FTP_HOST" . "$FILE_ID"
Would report the number of files whose name contains $FILE_ID
and ends in .txt
in your landing directory whatever $FILE_ID
may contain (even things like spaces or ;
which would be a problem for sftp
) and whatever the file names there contain (even newline characters which would be a problem for wc -l
).
(latin1
encoding to not try to do UTF-8 decoding and work with arbitrary byte values in file paths).
To get the list of files in a shell array, with zsh
:
files=( ${(0)"$(
perl -MNet::SFTP::Foreign -l0 -e '
($host, $dir, $id) = @ARGV;
$s = Net::SFTP::Foreign->new($host, autodie => 1, fs_encoding => latin1);
print for @{
$s->ls($dir, names_only => 1, wanted => qr/\Q$id\E.*\.txt\z/s)
}' -- "$FTP_UNAME@$FTP_HOST" . "$FILE_ID")"}
)
With bash 4.4+:
readarray -td '' files < <(
perl -MNet::SFTP::Foreign -l0 -e '
($host, $dir, $id) = @ARGV;
$s = Net::SFTP::Foreign->new($host, autodie => 1, fs_encoding => latin1);
print for @{
$s->ls($dir, names_only => 1, wanted => qr/\Q$id\E.*\.txt\z/s)
}' -- "$FTP_UNAME@$FTP_HOST" . "$FILE_ID")
Though you lose the exit status of perl
.
()
,[]
etc. So the choice is between absolute (?) correctness with knowledge of a programming language, versus using the shell with minimal quoting and some file naming discipline. – Vilinkameni Feb 06 '24 at 17:49