6

I can't seem to make this command work:

scp fx-devel1:/home/user/gege/feed.zip;2 fx-devel2:/home/user/gege/feed.zip;3

I have tried:

scp "fx-devel1:/home/user/gege/feed.zip;\2" "fx-devel2:/home/user/gege/feed.zip\;3"

yet it seems that it only escapes the first ';' as this appears:

feed.zip;2                                                    100%  302KB 301.8KB/s   00:00
bash: 3: command not found

How do I make it work? I would like to include the ';3' in the name of the destination file.

EDIT: I can make it work when I improvise -- I have to use mv after transferring:

scp 'fx-devel1:/home/user/gege/feed.zip\;2' fx-devel2:/home/user/gege/feed.zip

ssh fx-devel2 mv /home/user/gege/feed.zip '/home/user/gege/feed.zip\;3'

But that means a lot more time. When transferring thousands of file, that could almost double the time accessing the servers.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
NightEye
  • 163
  • 6

2 Answers2

2

This worked for me:

/tmp $ ls foo*
'foo;2'
/tmp $ scp 'foo;2' 'localhost:/tmp/foo\;3'
Password:
foo;2                                            100%    0    0.0KB/s    0.0KB/s    00:00
/tmp $ ls foo*
'foo;2'  'foo;3'
/tmp $
Andy Dalton
  • 13,654
  • 1
  • 25
  • 45
1

In bash single (') and double (") quotes can either be used to quote a semicolon. There is no need to put an extra backslash inside the quoted string to quote these. You need the backslash to quote some special chars inside double quotes but semicolon is not one of them (" and \ for example are).

After a test I conclude that the Command not found message comes from the remote machine! So the above is true, at least not as long as one shell is involved! But here the destination file name seems to be passed to the shell on the other side somehow.

So if your file is called /home/user/gege/feed.zip;2 and should be saved as /home/user/gege/feed.zip;3 on the other machine either of these should work

scp 'fx-devel1:/home/user/gege/feed.zip;2' 'fx-devel2:/home/user/gege/feed.zip\;3'
scp "fx-devel1:/home/user/gege/feed.zip;2" "fx-devel2:/home/user/gege/feed.zip\\;3"
scp fx-devel1:/home/user/gege/feed.zip\;2 fx-devel2:/home/user/gege/feed.zip\\\;3

You can make some tests how quoting in the shell works for yourself (and obviously read the relevant part of the man page) with this function:

test_quoting () {
  printf 'Number of args: %s\n' "$#"
  printf 'First arg: %s\n' "$1"
}
test_quoting abc def
test_quoting "abc def"
test_quoting 'xyz;123'
test_quoting foo\;bar
test_quoting 'foo\;bar'
# and so on
Lucas
  • 2,805
  • 1
  • 14
  • 24