When using backticks (in perl) i seem to have some sort of inconsistency with brace expansion
print `ls -d ~/{a,b}`;
Works fine, but when i try
print `ls -d ~/{a}`;
I get:
ls: cannot access /home/user/{a}: No such file or directory
I have tried all sort of quoting, spacing and escapes but to no avail. my question is, is there a way to force the expansion? I realize I can avoid the issue all together if I just glob the stuff myself, but I'm curious about this behavior
i tried this under both bash and tcsh. when used directly under tcsh, the command works, but under bash it doesn't
Now, after your several edits, I understand that you may be using two different shells. And, also, that the one calling the shell is perl, not you.
So, to cover the three elements:
In bash. A simple {a} will not be expanded:
$ echo ~/{a,b}
/home/user/a /home/user/b
$ echo ~/{a}
/home/user/{a}
Which is searched as a file by ls
, and not found.
The relevant part of the manual man bash is (emphasis mine):
A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression.
A {a}
is lacking a required comma.
The only alternative is to actually use
$ print `ls -d ~/a`
In tcsh
: A simple {a} will be expanded (as in a csh
shell):
Using >
as shell indicator for tcsh prompt:
> echo --{a,b}++
--a++ --b++
> echo --{a}++
--a++
As a simple {}
also will:
$ echo --{}++
--++
The only braces that will not be removed will be {}
and {
and }
.
IIF (if and only if) they are recognized as "words". Most commonly surrounded by spaces:
$ echo --{}++ == {} .. { :: } aa { bb
--++ == {} .. { :: } aa { bb
If a {
or a }
appear as part of a word, without the matching brace, is an error:
> echo aa{bb
Missing '}'.
The only description of this on the man tcsh is really short (unclear?):
> As a special case the words `{', `}' and `{}' are passed undisturbed.
If the shell commands are called from perl, in the cases that do call a shell, like under Unix systems, the shell called is /bin/sh
.
An an additional twist, the /bin/sh
is served by bash in most linux systems, by tcsh in FreeBSD and by ksh or csh in OpenBSD.
It becomes difficult to predict the output of a perl called /bin/sh
.
You could make sure that an specific shell is called:
#!/usr/bin/perl
print `/bin/tcsh -c 'ls -d ~/{a,b}'`;
Now the question remains: