The command and arguments given to ssh
will be handled like this (from the OpenSSH ssh(1)
manual):
If a command is specified, it will be executed on the remote host instead
of a login shell. A complete command line may be specified as command,
or it may have additional arguments. If supplied, the arguments will be
appended to the command, separated by spaces, before it is sent to the
server to be executed.
This means that you will have to arrange your command in such a way that adding the list of filenames to the end results in a valid shell command. You also need to ensure that each filename is properly quoted.
Assuming your shell on the local host is bash
, you may do this:
ssh "$remote" '
t () {
for name do
[ -e "$name" ] && printf "%s exists\n" "$name"
done
}
t' "${list[@]@Q}"
Or, as a "one-liner":
ssh "$remote" 't () { for n do [ -e "$n" ] && printf "%s exists\n" "$n"; done; }; t' "${list[@]@Q}"
This runs a POSIX shell fragment on the remote machine, which starts by defining a function, t
. The function iterates over its arguments and writes out which ones correspond to existing names. The function is called after defining it, and ssh
will append the elements of the list generated by "${list[@]@Q}"
as arguments to the function call.
The expansion "${list[@]@Q}"
is carried out by the local bash
shell and will quote each element in the list list
(see Stéphane's comments below for caveats).
An example where I connect to a system where only the mbox
entry in the given list exists:
$ list=( 1 2 3 mbox "my * mbox" )
$ printf '%s\n' "${list[@]@Q}"
'1'
'2'
'3'
'mbox'
'my * mbox'
$ ssh "$remote" '
t () {
for name do
[ -e "$name" ] && printf "%s exists\n" "$name"
done
}
t' "${list[@]@Q}"
mbox exists
If the local shell is the zsh
shell, you would use ${(qq)list}
in place of "${list[@]@Q}"
.
declare
(akatypeset
) in a heredoc on Stack Overflow at stackoverflow.com/questions/76583980/…. It's a good alternative to justscp
-ing a script.