0

I understand that running one command after another is done in bash using the following command

command1 && command2

or

command1; command2

or even

command1 & command2

I also understand that a command stored in a bash variable can be run by simply firing the variable as:

TestCommand="ls"
$TestCommand

Doing the above will list all the files in the directory and I have tested that it does.

But doing the same with multiple commands generates an error. Sample below:

TestCommand="ls && ls -l"
$TestCommand
ls: cannot access &&: No such file or directory
ls: cannot access ls: No such file or directory

My question is why is this happening and is there any workaround?

And before you bash me for doing something so stupid. The preceding is just to present the problem. I have a list of files in my directory and I am using sed to convert the list into a single executable string. Storing that string in a bash variable, I am trying to run it but failing.

5
  • The dangerous way is to eval that string. You want to execute all the files in a directory? Do you want to abort if one fails? You could go for a for loop. Commented Dec 8, 2015 at 6:50
  • When you want to execute custom commands by giving them a name write a function e.g. myfunction() { include your commands here }. You can then call myfunction any time after it is declared in your code. Also recognize that command1 && command2 or command1 || command2 are called compound commands. Including a ';' following a command is simply and end-of-line. I don't believe your bitwise & of commands is doing what you think it is. Commented Dec 8, 2015 at 7:17
  • @DavidC.Rankin, I just wanted to know why this is not working. And I observed the behaviour of using ';' is same as that of '&&' and so is '&'. I couldn't spot the difference. Would you know the difference? Commented Dec 8, 2015 at 8:07
  • 1
    The ';' is not the same as &&. The ';' is just an end-of-line it has no bearing on whether there was a successful completion of the command before it. && is a compound command operator that effectively says execute command2 if, and only if there is a successful completion of command1 in command1 && command2. Try it ls foo; printf "after foo\n" and then ls foo && printf "after foo\n" Now try ls /home || printf "after foo\n" (|| meaning if command1 fails, then command2. command1 & command2 is nothing but a bitwise and of the returns of 1 & 2. Hope this helped. Commented Dec 8, 2015 at 8:57
  • Note, I stand corrected an '&' separator or terminator shall cause asynchronous execution of the preceding list of compound commands. (e.g. it causes the preceding command to be executed in the background, rather than synchronously with the command that follows. Note. compound command is also known as an asynchronous list or and-or list in POSIX shell. (see e.g. Asynchronous Lists ) I wasn't thinking about it as a connector, but it is, just strange to think of it that way -- after 20 years Commented Dec 8, 2015 at 9:11

1 Answer 1

1

When you put two command in a single string variable, it is executed as single command. so when you are using "$TestCommand" to execute two "ls" commands, it is executing only one(first) "ls" command. it considers && and ls(second) as argument of first ls command.

As your current working directory is not having any files named && and ls it is returning error :

    ls: cannot access &&: No such file or directory
    ls: cannot access ls: No such file or directory

So, basically your commands behaves like this

    ls file1 file2 -l

and it will give you output like this if file1 and file2 exists:

    HuntM@~/scripts$ ls file1 file2 -l
    -rw-r--r-- 1 girishp staff 0 Dec  8 12:44 file1
    -rw-r--r-- 1 girishp staff 0 Dec  8 12:44 file2

Now your solution:

You can create function OR one more script to execute 2 commands as below:

caller.sh

    #!/bin/bash
    myLs=`./myls.sh`
    echo "$myLs"

myls.sh

    #!/bin/bash
    ls && ls -l
Sign up to request clarification or add additional context in comments.

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.