Search code examples
linuxbashubuntuubuntu-10.10

Command Substitution working on command line but not in script


Using ubuntu 10.10 I have the following that I run on the command-line:

result="$(ls -d !(*.*))"
chmod +x $result

This gets a list of files that have no extensions and makes them executable.

But when I move it to a script file (shell) it does not work. From what I have read around the forum this is something to do with command substitution being run in a different a subshell.

But I could not find a solution yet that works in my scrpt :(

So how do you get the result of a command and store it in a variable within a script?


Solution

  • (Since @user000001 does not seem to write their comment into an answer, I'll do the toiling of writing the answer. So credit should got to them, though.)

    The feature you are using is the extglob (extended globbing) feature of the bash. This is per default enabled for interactive shells, and per default disabled for non-interactive shells (i. e. shell scripts). To enable it, use the command shopt -s extglob.

    Note that this command only has effect for lines below it:

    shopt -s extglob
    ls -d !(*.*)
    

    It does not effect parsing of the same line:

    shopt -s extglob; ls -d !(*.*)   # won't work!!
    

    In general I want to warn about using such special features of the bash. It makes the code rather unportable. I'd propose to use POSIX features and tools instead which enable porting the code to another platform rather easily, and they also represent a certain subset of possibilities more developers understand without having to consult the documentation first.

    What you want to achieve could also be done using find. This also has the advantage of being unproblematic in combination with strange file names (e. g. containing spaces, quotes, etc.):

    find . -maxdepth 1 -type f -name '*.*' -o -exec chmod +x "{}" \;