Search code examples
bashshellunixfuser

Unix how to store fuser command output to a variable


I'm a newbie in scripting and I have this problem:

I want to use the fuser command to check if a file with that name is present. I want to save the output of the command and later use it to rename the file before loading.

I have tried the following:

#!/bin/bash
file_name='test'
echo 'file_name before: '$file_name
file_name=`fuser FILE_DIR/SD/Test_file_??????????????.dat`
echo 'file_name after: '$file_name'

However, the result of the above code is:

-bash-3.00$ script.sh
file_name before :test
FILE_DIR/SD/Test_file_20180823120345.dat
file_name after:

The output of the command is not getting stored in variable but getting displayed in screen and I can't figure out why!

What I want to do is to store Test_file_20180823120345.dat in the file_name variable, and then remove the timestamp from that and rename the file to Test_file_20180823.dat.

Then after loading the data in the staging table again rename the file to the old file name that we have received and then archive the file with its original name.


Solution

  • Your problems is a missing closing single quote in:

    echo 'file_name before: '$file_name
    

    (which is also why you had to unbalance the quotes in echo 'file_name after: '$file_name' on the last line to get the script to run)

    Instead, simply double-quote the entire string for echo that will allow expansion of your variable file_name, e.g.

    echo "file_name after: $file_name"
    

    Further, avoid using backticks for command substitution, instead use the $(...) form, e.g.

    file_name=$(fuser FILE_DIR/SD/Test_file_??????????????.dat)
    

    Or re-written it could be:

    #!/bin/bash
    
    file_name='test'
    echo "file_name before: $file_name"
    file_name=$(fuser FILE_DIR/SD/Test_file_??????????????.dat)
    echo "file_name after: $file_name"
    

    (note: your matching with fuser will only match a pattern with 14 characters after Test_file_ followed by .dat -- which may be what you want, but it can probably be written in a cleaner way depending on the possibilities of ??????????????)

    While fuser will provide an error, you may also want to get in the habit of validating that your command substitution returned a variable by testing whether file_name is empty after the call to fuser, e.g.

    #!/bin/bash
    
    file_name='test'
    echo "file_name before: $file_name"
    file_name=$(fuser FILE_DIR/SD/Test_file_??????????????.dat)
    if [ -z "$file_name" ]; then
        echo "error: no file matched pattern" >&2
    else
        echo "file_name after: $file_name"
    fi
    

    Look things over and let me know if you have further questions.