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
  • 320,670
  • 36
  • 633
  • 936
m19v
  • 133
  • 1
  • 7
  • 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
    Related: [How can we run a command stored in a variable?](//unix.stackexchange.com/q/444946) – Kusalananda Jan 31 '20 at 12:57
  • 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 >
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Panki
  • 6,221
  • 2
  • 24
  • 33
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
  • 35,934
  • 12
  • 91
  • 140