Re: [SHELL] Detect backslash in command line args
by choroba (Cardinal) on Jul 08, 2013 at 14:17 UTC
|
I am not sure about cmd.exe, but for *nix shells, it is not possible. The backslash is interpreted by the shell running the prompt, which means the script gets the string without the backslash.
| [reply] |
|
Yes, that's one of the bigger differences between the MS family and the Unix family. In Unix it's the shell's task to do command line parsing, globbing, etc. while COMMAND.COM and CMD.EXE just call the program and let it do all the rest. So, the answer to the OP: in Unixish systems, there isn't.
| [reply] |
|
echo comma\nd with backslash | cat -v
But the shell will parse the backslash - so in one sense, you don't actually _need_ to detect it, because it isn't there any more by the time your script uses it. | [reply] [d/l] |
Re: [SHELL] Detect backslash in command line args
by LanX (Saint) on Jul 08, 2013 at 14:30 UTC
|
Backslash is an escape character which needs to be escaped ... you might already guess ... with a backslash.
The shell doesn't act very different to double-quoted strings in Perl.
UPDATE
You have a misconception here
> With MS Windows's cmd.exe shell we can force an exception if any args passed via the command line contain a backslash:
the same with Unix, just
> So ... if someone does perl script.pl arg\one in one of these shells, is there any way that script.pl can detect the backslash contained in that command line argument ?
In your example you are not passing a backslash, just an escaped "o", which is most probably just a simple "o"¹. To be able to pass a backslash you need to double it!!!
Cheers Rolf
( addicted to the Perl Programming Language)
¹) yep
lanx@nc10-ubuntu:~$ perl -le 'print ord(chomp($ARGV[0]))' \o
48
lanx@nc10-ubuntu:~$ perl -le 'print ord(chomp($ARGV[0]))' o
48
| [reply] [d/l] |
Re: [SHELL] Detect backslash in command line args
by Laurent_R (Canon) on Jul 08, 2013 at 17:44 UTC
|
$ perl -e 'die "error: @ARGV[0]" if @ARGV[0] =~ /\\/' foo\\bar
error: foo\bar at -e line 1.
| [reply] [d/l] |
|
perl -e 'die "error: @ARGV[0]" if @ARGV[0] =~ /\\/' foo\\bar
That works, but passing 'foo\\bar' is not an error. The error I want to catch is when I pass 'foo\bar'.
Cheers, Rob
| [reply] |
|
| [reply] |
|
Re: [SHELL] Detect backslash in command line args
by mtmcc (Hermit) on Jul 08, 2013 at 21:20 UTC
|
That's a very good problem.
As others have mentioned, osx/linux strips the command line before passing the arguments to perl, and so I don't know of any way that perl could "see" the unprocessed arguments.
bash has handy tools that can retrive historical command line arguments. The catch as I see it is that while ~/.bash_history is fully available to your perl script, and contains the unprocessed command line arguments, it only updates when you log out of the shell, and so won't contain the last command issued.
bash does keep a record of unprocessed command lines in working memory. These can be printed at the command line for example with:
history | tail -5
where the last digit determines the number of previous commands to print at the terminal. These are also unprocessed. The problem is that the history command isn't a bash executable, and so doesn't work in the context of a system() call by Perl. Maybe someone knows how to get around this? Would be interested to find the answer.
Michael
| [reply] [d/l] [select] |
|
The problem is that the history command isn't a bash executable, and so doesn't work in the context of a system() call by Perl.
Might Term::UI::History be of help here ?
Looks like accessing the shell's history is the only hope.
Thanks for the confirmations that this isn't trivial anywhere except MS Windows shells (which, I'm assuming, arises because on Windows the backslash is not necessarily an escape). I have a perl script that I can use to transfer files from my Windows 7 box to my Ubuntu box. If I do perl get.pl C:/some/file all is fine. I was merely hoping to catch the error when I inadvertently do perl get.pl C:\some\file. It's not really such a big deal because I eventually find out about the error anyway - and it's not actually an error that I'm liable to make with great frequency.
Cheers, Rob
| [reply] [d/l] [select] |
|
It doesn't arise on Windows, because the OS doesn't process the command line, just hands it straight to perl.
I'm not certain that Term::UI::History wouldn't work, but because it couldn't be running when the command line is processed by the OS, I can't quite see how it would work.
If your main concern is that you might ask perl to get a file that doesn't exist, I would use something like:
die "$fileName not found.\n\n" if !-e $fileName;
If it's writing to a new file, maybe you could similarly check that the directory exists, before writing to the file ?
In any case, it's still a good question, and if you do figure out an answer, please let me know!
Michael
| [reply] [d/l] |