1

Can I join two commands defined as String and run as one. E.g.

var="ls -alt"
var2="| grep usersfile"
var3="| grep usersfolder"

Following example for joining commands does not work.

a. '{$var & $var2;}'

b. '{$var & $var3;}'

What I what is:

a. run "$var $var2" and get "ls -alt | grep usersfile"

or

b. run "$var $var3" and get "ls -alt | grep usersfolder"

Kusalananda
  • 333,661
m19v
  • 143
  • Welcome to the site. Could you elaborate what you mean with the statements a. '{ etc. }' and b. '{ etc. }'. Do you want to assign the "joint command" to a variable a and b respectively which you then want to "execute"? – AdminBee Jan 31 '20 at 12:37
  • Thanks. I will edit and put a comment. – m19v Jan 31 '20 at 12:40
  • 2
    What is it that you actually want to do? It looks as if you want to get the ls -lt output for something containing the string userfolder and/or the string userfile. Could you rephrase your question to show what the underlying issue is. Grepping the output of ls is very rarely the correct approach. For example, why would you need to store the ls command in a variable? Why not create a shell function instead? – Kusalananda Jan 31 '20 at 12:49
  • 1
  • 1
    seems like an xy problem and if you are trying to do what I think you are, you should make a function instead. – jesse_b Jan 31 '20 at 14:24

2 Answers2

2

Yes, you can do this by using eval.

$ var="ls -alt"
$ var2="| grep usersfile"
$ var3="| grep usersfolder"
$ eval "$var$var2"
< Output of ls -alt | grep userfile >
$ eval "$var$var3"
< Output of ls -alt | grep usersfolder >
Panki
  • 6,664
1

You probably shouldn't do it this way. Depending on what you are actually trying to accomplish there are likely other options:

If you are just trying to have a dynamic option to select your search string you could do something like this instead:

#!/bin/bash
pattern=$1

ls -alt | grep "${pattern:-.}"

This will search for whatever your first positional parameter is, or anything if none is provided.

Or if you're trying to act on some condition:

#!/bin/bash

cmd=(ls -alt)
p1=usersfile
p2=usersfolder

if [[ condition1 ]]; then
    p=$p1
elif [[ condition2 ]]; then
    p=$p2
fi

"${cmd[@]}" | grep "$p"

Or in a function:

#!/bin/bash

ls_func () {
    local p=$1
    ls -alt | grep "${p:-.}"
}

while getopts p:c: opt; do
    case $opt in
        c)  command=$OPTARG;;
        p)  pattern=$OPTARG;;
    esac
done

if [[ $command == 'ls' ]]; then
    ls_func "$pattern"
fi
jesse_b
  • 37,005