description
The copy command is a thin veneer user interface to FS.Copy. In particular: FS.Copy[from: from, to: to, keep: createKeep, attach: TRUE]. createKeep is a global variable in FSFileCommandsImpl.mesa. FS.Copy will be called with attach: FALSE if the -c switch is set.
The first form of copy is Copy to ← from. This form copies a single file.
FS uses the current working directory if either to or from are not full path names.
The second and third forms of Copy create a series of FS attachments from local names to each remote name matched by an argument. This is a very fast way to establish a local copy of a complete remote subtree. Since attachments are used, the bits of the files are only retrieved when needed. (However, if the -c switch is set, the actual bits are copied!)
The pattern '* does not match the characters '/ or '>, but the pattern "**" does. This means that unless you use "**", copy will not copy any files in subdirectories. If the -r switch is set, (and ** is used) then Copy will retain the directory structure of the source. If the -r switch is absent, the shortnames of the source files will be retained, but subdirectory structure will be lost.
Here is the discussion of Copy from FS.mesa.
(To be updated from the appropriate version of FSDoc.tioga.)
The version of the "to" file created is one larger than the existing !H version, unless "to" is a GName on a server that does not support version numbers, in which case an existing global file will be overwritten.
Case 1: "to" is a GName and "attach" is FALSE — FS does an FS.Open[from, read, wantedCreatedTime, remoteCheck, wdir] and stores the contents and properties of the opened file directly in the new "to" file on the remote server.
Case 2: "to" is an LName and "attach" is FALSE — FS does an FS.Open[from, read, wantedCreatedTime, remoteCheck, wDir] to generate a "from" open file, and FS.Create[to, setKeep, keep, wDir] to generate a "to" OpenFile. The contents and properties are copied from the "from" OpenFile to the "to" OpenFile, and both are closed. (In the case of copying from an uncached global file, the global file is not added to the cache. The only pages allocated on the local volume are those needed to hold the target local file.)
Case 3: "to" is a GName, "attach" is TRUE, and "from" is a LName — Things proceed as in case 1, except a "write" lock is acquired for the "from" file. Once the transfer is completed, the LName is attached to the GName. Case 3 is used by "SModel".
Case 4: "to" is an LName, "attach" is TRUE, and from" is a GName — Like case 2 except that instead of an actual transfer of contents and properties, the LName is attached to the GName / created-time. If no "wantedCreatedTime" is specified, or if "remoteCheck" is TRUE, then FS.FileInfo[to, wantedCreatedTime, TRUE] is performed first to determine/check the version number and created-time for the GName and any resulting FS.Error is passed on to the client. When "remoteCheck" is FALSE (but a wantedCreatedTime" is specified) then the attachment is made to the "from" and "wantedCreatedTime" arguments without checking either the remote server or the cache. Case 4 is used by "BringOver".
Case 5: both "from" and "to" are LNames, or both are GNames, and "attach is "TRUE" — FS proceeds as though "attach" were FALSE (see cases 1 and 2 above).
warnings
There is presently no way to change the value of createKeep, but the SetKeep command will change the keep for a particular file.
If a pattern does not include a version number specification, then !H is appended.
If a pattern which matches a subtree (files in subdirectories) is used, the subdirectory structure will be lost.
It is likely that Copy remote-pattern!* does not do what you think!
% Copy /Ivy/Stewart/temp/W1aw.txt!*
///wierd/w1aw.txt ← [Ivy]<Stewart>temp>w1aw.txt!1
///wierd/w1aw.txt ← [Ivy]<Stewart>temp>w1aw.txt!2
///wierd/w1aw.txt ← [Ivy]<Stewart>temp>w1aw.txt!3
% list w1aw.txt
[]<>wierd>w1aw.txt!2 []<>wierd>w1aw.txt!3
%
The attachments were made in the order shown, but the default keep = 2 has causes w1aw.txt!1 to fall off the edge. There is no guarantee that the local w1aw.txt!2 is the same as the remote w1aw.txt!2, as can be seen by the following example:
% Copy /Ivy/Stewart/temp/W1aw.txt!*
///wierd/w1aw.txt ← [ivy]<Stewart>temp>w1aw.txt!1
///wierd/w1aw.txt ← [ivy]<Stewart>temp>w1aw.txt!2
///wierd/w1aw.txt ← [ivy]<Stewart>temp>w1aw.txt!3
% list w1aw.txt
[]<>wierd>w1aw.txt!5 []<>wierd>w1aw.txt!6
%