Author Topic: REXX and double quoted INPUT parameter strings  (Read 222 times)

Dariusz Piatkowski

  • Hero Member
  • *****
  • Thank You
  • -Given: 14
  • -Receive: 17
  • Posts: 749
    • View Profile
REXX and double quoted INPUT parameter strings
« on: September 14, 2020, 02:18:09 am »
So let me set the context of the question: I wrote a little REXX script to automate the execution of RSYNC. The goal is to have this scheduled in CRON2 to allow me to copy the contents of the LOCAL drives over to the NAS box, or if needed to a LOCAL to LOCAL copy (such as a backup run to another HDD).

The INPUT parameters to the REXX script are various LOCAL folders as well as the NAS box folder where I'm going to copy the stuff to, basically the SOURCE and TARGET folder destinations.

So while I have this working well enough to handle any folder names where no space exists in the name:

1) G:\DESKTOP\AUTOMOTIVE

...I have ran into some difficulties trying to get this working for the folders that do have a space:

2) G:\DESKTOP\MISC INFO

Clearly passing such a folder name as an un-double quoted value just causes the REXX script to interpret the first space as a argument separator, subsequently:

CLI  => rsync_backup NAS G:\DESKTOP\MISC INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO

causes the following args to be identified:

Code: [Select]
SOURCE => G:\DESKTOP\MISC
TARGET => INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO

Now if I do apply the double quotes, just like one would need to when attempting to work with such a folder through a CLI window:

CLI => rsync_backup NAS "G:\DESKTOP\MISC INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"

causes the following args to be identified:

Code: [Select]
SOURCE => "G:\DESKTOP\MISC
TARGET => INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"

The REXX code I use to pull in the arguments is pretty basic:

Code: [Select]
/* parse the command line to pick up the BACKUP_TYPE, SOURCE and TARGET locations */
arg backup_type source target

I looked through all my REXX PDFs and INFs but haven't found anything that spells out how to get around this.

So...any ideas how to handle this?

Thanks!

FYI: I've attached the actual rsync_backup.cmd file, but with a TXT extension.

Pete

  • Hero Member
  • *****
  • Thank You
  • -Given: 1
  • -Receive: 47
  • Posts: 1041
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #1 on: September 14, 2020, 04:10:28 am »
Hi Dariusz

Have you tried omitting the 2 middle double quotes ie

 rsync_backup NAS "G:\DESKTOP\MISC INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO"


Regards

Pete


Dariusz Piatkowski

  • Hero Member
  • *****
  • Thank You
  • -Given: 14
  • -Receive: 17
  • Posts: 749
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #2 on: September 14, 2020, 05:35:12 am »
Hey Pete!

..Have you tried omitting the 2 middle double quotes ie

 rsync_backup NAS "G:\DESKTOP\MISC INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO"
...

Yup, tried that as well, the darn space is still being treated as the parm separator:

Code: [Select]
SOURCE => "G:\DESKTOP\MISC
TARGET => INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO"

BUUUTTTT...that gave me an idea: why not try to use the arg separator to tell REXX which special character divides up the SOURCE from TARGET?

So I now have the following code:

Code: [Select]
arg backup_type source"-"target

where the "-" tells REXX to look for that dash in the input CLI.

Now I can actually kick things off with: rsync_backup NAS "G:\DESKTOP\MISC INFO\"-"V:\PUBLIC\DOCUMENTS\MISC INFO"

which gives me the following result:

Code: [Select]
SOURCE => "G:\DESKTOP\MISC INFO\"
TARGET => "V:\PUBLIC\DOCUMENTS\MISC INFO"

So at least I passed that hurdle, what remains now is to figure out why rsync itself chokes on those parameters being passed as-is:

Code: [Select]
...
RSYNC CLI => --dry-run --archive --delete --progress --stats --whole-file --no-xattrs --human-readable --quiet --exclude-from=G:\mptn\etc\rsync_exclude --log-file=G:\tmp\log\rsync_NAS_backup.log  "G:\DESKTOP\MISC INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"

RSYNC started:     09/13/20 - 23:43:39...
[sender] change_dir chdir failed for G:/DESKTOP/MISC INFO" V:/PUBLIC/DOCUMENTS at util.c(1117)
rsync: change_dir "G:/DESKTOP/MISC INFO" V:/PUBLIC/DOCUMENTS" failed: No such file or directory (2)
[sender] change_dir G:/DESKTOP/MISC INFO" V:/PUBLIC/DOCUMENTS failed at flist.c(404)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1168) [sender=3.0.9.1]
...

It looks to me like it does strip out some of the double quotes, but I'm not quite sure what logic it uses to do so. Trying with a single quote did not work, result was different, just not what I needed.
« Last Edit: September 14, 2020, 05:54:49 am by Dariusz Piatkowski »

Lars

  • Hero Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 64
  • Posts: 602
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #3 on: September 14, 2020, 07:27:38 am »
Why don't you just use strip (with " leading and trailing) after separating the arguments?

Andreas Schnellbacher

  • Hero Member
  • *****
  • Thank You
  • -Given: 1
  • -Receive: 31
  • Posts: 567
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #4 on: September 14, 2020, 11:40:47 am »
Here's how to parse enquoted args correctly. It allows for multiple args, each may be enclosed in double quotes.

First the output:
Code: [Select]
> TestParseArgs.cmd "G:\DESKTOP\MISC INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"
1: Rest = ["G:\DESKTOP\MISC INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"]
1: Next = [G:\DESKTOP\MISC INFO\]
2: Rest = ["V:\PUBLIC\DOCUMENTS\MISC INFO"]
2: Next = [V:\PUBLIC\DOCUMENTS\MISC INFO]
Arg.1 = G:\DESKTOP\MISC INFO\
Arg.2 = V:\PUBLIC\DOCUMENTS\MISC INFO

Here's the script:
Code: [Select]
/* Parse multiple args optionally enclosed in double quotes */

/* Parse args */
PARSE ARG Args
Args = STRIP( Args)

/* Init vars */
Arg. = ''
Arg.0 = 0
Rest = Args

/* Parse Rest */
DO WHILE Rest <> ''
   /* Advance arg counter */
   NumArgs = Arg.0 + 1
   SAY NumArgs': Rest = ['Rest']'
   
   /* Parse Next from Rest */
   IF LEFT( Rest, 1) = '"' THEN
      PARSE VAR Rest '"'Next'"' Rest
   ELSE   
      PARSE VAR Rest Next Rest
   SAY NumArgs': Next = ['Next']'

   /* Strip multiple spaces between args */     
   Rest = STRIP( Rest)

   /* Save Next to Arg. array */
   Arg.NumArgs = Next
   Arg.0 = NumArgs
END

/* Test Arg. array */
DO i = 1 TO Arg.0
   SAY 'Arg.'i' = 'Arg.i
END

EXIT


Dariusz Piatkowski

  • Hero Member
  • *****
  • Thank You
  • -Given: 14
  • -Receive: 17
  • Posts: 749
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #5 on: September 14, 2020, 03:46:05 pm »
Hey Lars,

Why don't you just use strip (with " leading and trailing) after separating the arguments?

I'm not sure I follow.

If you are suggesting that I use strip to remove the " after I successfully recognize the SOURCE & TARGET folder names alright, I am following you.

The problem though becomes that rysnc still fails since the OS/2 way of handling such a path name is to wrap in double quotes.

Therefore, the following CLI:

rsync --dry-run --archive --delete --progress --stats --whole-file --no-xattrs --human-readable --quiet --exclude-from=G:\mptn\etc\rsync_exclude --log-file=G:tmp\log\rsync_NAS_backup.log  G:\DESKTOP\MISC INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO

still gives me the following error from rsync:

Code: [Select]
rsync: link_stat "G:/DESKTOP/MISC" failed: No such file or directory (2)
[sender] change_dir chdir failed for INFO at util.c(1146)
rsync: change_dir "G:/INFO" failed: No such file or directory (2)
[sender] change_dir INFO failed at flist.c(404)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1168) [sender=3.0.9.1]

So I wonder if perhaps the bigger problem here is that our port of rsync does not handle the native OS/2 way of passing path names which contain a space in it?

Dariusz Piatkowski

  • Hero Member
  • *****
  • Thank You
  • -Given: 14
  • -Receive: 17
  • Posts: 749
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #6 on: September 14, 2020, 03:47:39 pm »
Hi Andreas!!!

Here's how to parse enquoted args correctly. It allows for multiple args, each may be enclosed in double quotes....

Aha...SUPER!

Yes, I will use that approach, it beats having to have that awkward separator in the CLI.

Thank you.

Andreas Schnellbacher

  • Hero Member
  • *****
  • Thank You
  • -Given: 1
  • -Receive: 31
  • Posts: 567
    • View Profile
Re: REXX and double quoted INPUT parameter strings
« Reply #7 on: September 14, 2020, 04:27:26 pm »
Code: [Select]
rsync --dry-run --archive --delete --progress --stats --whole-file --no-xattrs
 --human-readable --quiet --exclude-from=G:\mptn\etc\rsync_exclude
 --log-file=G:tmp\log\rsync_NAS_backup.log
  G:\DESKTOP\MISC INFO\ V:\PUBLIC\DOCUMENTS\MISC INFO

still gives me the following error from rsync:
[...]
Sure. Have you tried to enquote the dirnames?
Code: [Select]
rsync ... "G:\DESKTOP\MISC INFO\" "V:\PUBLIC\DOCUMENTS\MISC INFO"

If you call that from a REXX script, you have two choices: Use surrounding single quotes for the entire rsync call including args or double all contained double quotes and surround it with double quotes.

The single quote option would be much easier to read.

For automatically enquoting a filename, if required, I use something like this:
Code: [Select]
Enquote:
   rc = 0

   PARSE ARG Filename

   IF VERIFY( Filename, ' &|<>', 'M') <> 0 THEN
      Filename = '"'Filename'"'

   RETURN( Filename)

Then you could change the rsync call to:
Code: [Select]
Cmd = 'rsync ... 'Enquote( 'G:\DESKTOP\MISC INFO\') Enquote( 'V:\PUBLIC\DOCUMENTS\MISC INFO')
Cmd
and use either single or double quotes to make the interpreter submit that to CMD.EXE.

Edit: Damned. The third version of the Cmd should finally work. (Much easier when you have syntax highlighting.)
« Last Edit: September 16, 2020, 07:40:52 pm by Andreas Schnellbacher »