I am trying to remove files via ssh using by find and xargs. On the local machine command works correctly. I am using exception list also.
I have tried to changes brackets between ' ' and " " but it does not work.
save_files=(test1 test2)
On the local machine:
find / -mindepth 1 | grep -vE "$(IFS=\| && echo "${save_files[*]}")" | xargs rm -rf
via ssh:
su - user -c "ssh host find / -mindepth 1 | grep -vE '$(IFS=\| && echo "${save_files[*]}")' | xargs rm -rf"
In above ssh command xargs is performing locally. I need xargs on remote machine. Even I put find command in '' brackets like below:
su - user -c "ssh host 'find / -mindepth 1 | grep -vE '$(IFS=\| && echo "${save_files[*]}")' | xargs rm -rf'"
Can you try this?
su - user -c "ssh host 'save_files=test; find / -mindepth 1 | grep -vE "$save_files" | xargs rm -rf'"
Or after switching as root user try below one?
ssh host 'save_files=test; find / -mindepth 1 | grep -vE "$save_files" | xargs rm -rf'
The code for executing the command on a remote host:
su - user -c "ssh host 'find / -mindepth 1 | grep -vE '$(IFS=\| && echo "${save_files[*]}")' | xargs rm -rf'"
Is using double quote to pass the command to 'su -c', and then single quotes to pass the command to 'ssh' (which contain double quotes). However, the quoting does not support nesting, so that the quote in '$(IFS=... ... )' actually terminate the quote in 'find'.
You can execute the same with a 'set -vx' prefix, to see the expansion
su - owner -c "set -vx ; ssh localhost ...
and you will see
++ IFS='|'
++ echo 'test1|test2'
+ su - owner -c 'set -vx ; ssh localhost '\''set -x ; find /foo -mindepth 1 | grep -vE '\''test1|test2'\'' | xargs rm -rf'\'''
Password:
+ ssh localhost 'set -x ; find /foo -mindepth 1 | grep -vE test1'
+ 'test2 | xargs rm -rf'
-su: test2 | xargs rm -rf: command not found
+ find /foo -mindepth 1
+ grep -vE test1
find: ‘/foo’: No such file or directory
Proposed Solution:
I was not able to find a way to get three level quoting (very frustrating) Possible solution may be to create a helper script h.sh, which will perform the 'ssh' command, and then invoking the helper script with 'su - user '/path/to/helper.sh'
Starting another answer, trying again for one-liner, avoiding the intermediate script.
The key problem is the three level quoting, whereas shell support only two level quoting (double quote, single quote). I believe it might be possible to eliminate the need for the 3rd level of quoting by using backquote in the pattern, eliminating the need to put it into quotes.
IFS=\| P="${save_files[*]}" su - owner -c "ssh localhost 'set -vx ; find /tmp/xyz -mindepth 1 | grep -vE ${P//|/\\|} | xargs rm -rf'"
The solution create the pattern with 'escapes' - see '($P/|/\|}', eliminating the need to quote the pattern. Should work if the save_files does not have magic characters.
Notes:
First connect your Remote system and run the bash command whatever you need, like find and xargs
ssh root@MachineB 'bash command'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.