0

Today I encountered something quite strange

I have two scripts:

wrong.sh:

execute()
{ 
        ${@}
}

execute "ls -l | less"

right.sh:

execute()
{ 
        ${@}
}

execute ls -l | less

Running sh wrong.sh gives the following output:

ls: less: No such file or directory
ls: |: No such file or directory

While running sh right.sh gives me the same thing as running ls -l | less

May I know: (1) While running sh wrong.sh will give me that wrong output (2) How to modify the execute function so that running sh wrong.sh will gives me the same thing as running ls -l | less

Hans Lub
  • 5,513
  • 1
  • 23
  • 43
HK_175
  • 9
  • 1
  • 4
  • Quote the `$@` like this `"$@"` and don't quote the whole argument because the function will search for a literal `"ls -l | less"` which is a whole string but there is more to it than you're telling us, kindly give the real problem that you're trying to solve. – Jetchisel Mar 18 '21 at 08:44
  • 1
    Taking a guess at what you're trying to do checkout this link. https://mywiki.wooledge.org/BashFAQ/050 – Jetchisel Mar 18 '21 at 08:47

1 Answers1

1

In your wrong.sh invocation, you are trying to run a command with the rather unusual 12 byte long name ls -l | less (which might actually exist, say as /usr/bin/'ls -l | less')

If you want to interpret a string as a shell command, the easiest thing to do is:

sh -c "$command_as_string"

So in your case

execute()
{
    sh -c "$1" # no ${@} if you only intend to ever pass a single string
               # or $SHELL -c "$1" if you want the *same* shell as you're calling execute() from
}
Hans Lub
  • 5,513
  • 1
  • 23
  • 43