15

I have a file named cmd that contains a list of Unix commands as follows:

hostname
pwd
ls  /tmp
cat /etc/hostname
ls -la
ps -ef | grep java
cat cmd

I have another script that executes the commands in cmd as:

IFS=$'\n'
clear
for cmds in `cat cmd`
do
        if [  $cmds ] ; then
        $cmds;
        echo "****************************";
        fi
done

The problem is that commands in cmd without spaces run fine, but those with spaces are not correctly interpreted by the script. Following is the output:

patrick-laptop
****************************
/home/patrick/bashFiles
****************************
./prog.sh: line 6: ls  /tmp: No such file or directory
****************************
./prog.sh: line 6: cat /etc/hostname: No such file or directory
****************************
./prog.sh: line 6: ls -la: command not found
****************************
./prog.sh: line 6: ps -ef | grep java: command not found
****************************
./prog.sh: line 6: cat cmd: command not found
****************************

What am I missing here?

6 Answers 6

20

Try changing the one line to eval $cmds rather than just $cmds

Sign up to request clarification or add additional context in comments.

Comments

4

You can replace your script with the command

sh cmd

The shell’s job is to read commands and run them! If you want output/progress indicators, run the shell in verbose mode

sh -v cmd

Comments

2

I personally like this approach better - I don't want to munge the IFS if I don't have to do so. You do need to use an eval if you are going to use pipes in your commands. The pipe needs to be processed by the shell not the command. I believe the shell parses out pipes before the expanding strings.

Note that if your cmd file contains commands that take input there will be an issue. (But you can always create a new fd for the read command to read from.)

clear
while read cmds
do
        if [ -n "$cmds" ] ; then
        eval $cmds
        echo "****************************";
        fi
done < cmd

1 Comment

proDir=${PROJECT_DIR}, where PROJECT_DIR contain space in the directory. Tried with eval ${PROJECT_DIR} not working, Will anyone give suggestion?
1

Edit: Turns out this fails on pipes and redirection. Thanks, Andomar.

You need to change IFS back inside the loop so that bash knows where to split the arguments:

IFS=$'\n'
clear
for cmds in `cat cmd`
do
    if [ $cmds ] ; then
        IFS=$' \t\n' # the default
        $cmds;
        echo "****************************";
        IFS=$'\n'
    fi
done

Comments

0

EDIT: The comment by Ben Blank pointed out that my old answer was wrong, thanks.

Looks like you're executing commands as a single string, so bash sees them as the script/executable name.

One way to avoid that would be to invoke bash on the command. Change:

    if [  $cmds ] ; then
    $cmds;
    echo "****************************";
    fi

to

    if [  $cmds ] ; then
    bash -c $cmds
    echo "****************************";
    fi

3 Comments

Actually, he's having the opposite problem. Setting $IFS as he's done here causes for to break on on newlines, exactly as he wants. However, it's then attempting to interpret the entire string as a command name rather than a command with arguments.
by invoking bash -c you're starting a new process for each command. That seems excessive and might have surprising results. For example, if one of the commands is a cd command, subsequent commands won't be run in that other directory.
It would also prevent side effects from spilling over, like changes in PATH. So a separate process might be just what you want. I did vote for your solution though.
0
sed 'aecho "-----------"' cmd > cmd.sh; bash cmd.sh

sed 'aXX' appends XX to every line. This will not work for multiline-commands like:

for f in * 
do 
    something $f
fi

but for single-line commands in most cases, it should do.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.