Bash Off Topic

Home » CentOS » Bash Off Topic
CentOS 2 Comments

I have a simple bash script it will take arguments from a file that has quotes.

my file arg.txt would be this
-lt “*.txt”

my script file would be LS_ARG=`cat arg.txt`
ls $LS_ARG

it does not run properly:
sh -x ./arg.sh
++ cat arg.txt
+ LS_ARG=’-lt “*.txt”‘
+ ls -lt ‘”*.txt”‘
ls: cannot access “*.txt”: No such file or directory

How do I resolve that ? If the quotes are not in my file it all works fine. I think its because it looks like the extra single quotes it puts around the “*.txt” – or – ‘”*.txt”‘ – how do I do this ? This is just a short example of my larger need.

Thanks,

Jerry

2 thoughts on - Bash Off Topic

  • In general, shell utilities won’t expand a wildcard within quotes
    (double or single). As I think you’ve discovered, this works fine:

    echo ‘-lt *.txt’ > argfile ls $(< argfile) I think you’re going to need to provide a test case where the quotes are actually required.

  • I think it’s to do with when the wildcard * is expanded. The expansion is not done by ‘ls’, it is done by the shell – so when you do ‘ls *’, ls doesn’t see just the single argument ‘*’, it sees multiple arguments consisting of the filenames. Using a simpler example, a shell script
    ‘c’ is:

    #!/bin/bash
    echo $#
    echo “1:” $1
    echo “2:” $2

    i.e. it displays the number of and the first two arguments:

    $ ./c *
    4
    1: a
    2: a2

    So there are 4 arguments (not just one) because there are four files in the directory.

    You can turn off the expansion (aka globbing) with ‘set -f’

    $ set -f ; ./c * ; set +f
    1
    1: *
    2:

    (But you also have to turn off globbing in the ‘./c’ script as well –
    that’s a subshell and globbing isn’t inherited

    #!/bin/bash
    set -f
    echo $#
    echo “1:” $1
    echo “2:” $2

    if you don’t turn off globbing in the script, when $1 – which contains
    ‘*’ – is echoed, it is expanded at that point.)

    Putting quotes around the “*” stops the expansion – this is with globbing turned off in the script:

    $ ./c “*”
    1
    1: *
    2:

    Similarly, using ls:
    $ ls *
    a a2 arg.txt c
    $ set -f ; ls * ; set +f
    ls: cannot access ‘*’: No such file or directory
    $ ls “*”
    ls: cannot access ‘*’: No such file or directory

    I don’t know how this affects what you are trying to do though!

    BTW, the single quotes you see when tracing the shell script is, I
    think, just for display purposes, they aren’t actually part of the variables and are there just to show what is a single entity if there is any doubt.

    P.