[bash] Bash script - variable content as a command to run

I have a Perl script that gives me a defined list random numbers that correspond to the lines of a file. Next I want to extract those lines from the file using sed.

#!/bin/bash
count=$(cat last_queries.txt | wc -l)
var=$(perl test.pl test2 $count)

The variable var returns an output like: cat last_queries.txt | sed -n '12p;500p;700p'. The problem is that I can't run this last command. I tried with $var, but the output is not correct (if I run manually the command it works fine, so no problem there). What is the correct way to do this?

P.S: Sure I could do all the work in Perl, but I'm trying to learn this way, because it could help me in other situations.

This question is related to bash

The answer is


In the case where you have multiple variables containing the arguments for a command you're running, and not just a single string, you should not use eval directly, as it will fail in the following case:

function echo_arguments() {
  echo "Argument 1: $1"
  echo "Argument 2: $2"
  echo "Argument 3: $3"
  echo "Argument 4: $4"
}

# Note we are passing 3 arguments to `echo_arguments`, not 4
eval echo_arguments arg1 arg2 "Some arg"

Result:

Argument 1: arg1
Argument 2: arg2
Argument 3: Some
Argument 4: arg

Note that even though "Some arg" was passed as a single argument, eval read it as two.

Instead, you can just use the string as the command itself:

# The regular bash eval works by jamming all its arguments into a string then
# evaluating the string. This function treats its arguments as individual
# arguments to be passed to the command being run.
function eval_command() {
  "$@";
}

Note the difference between the output of eval and the new eval_command function:

eval_command echo_arguments arg1 arg2 "Some arg"

Result:

Argument 1: arg1
Argument 2: arg2
Argument 3: Some arg
Argument 4:

line=$((${RANDOM} % $(wc -l < /etc/passwd)))
sed -n "${line}p" /etc/passwd

just with your file instead.

In this example I used the file /etc/password, using the special variable ${RANDOM} (about which I learned here), and the sed expression you had, only difference is that I am using double quotes instead of single to allow the variable expansion.


Your are probably looking for eval $var.