Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to execute specific line of text file in bash. I was wondering is it possible to do that without copying that line in a new file and executing it?

share|improve this question

5 Answers 5

up vote 2 down vote accepted

Building on @kev's answer (without piping to a new bash): Take his script source

script.sh

echo hello
echo world
echo foo
echo bar

and execute a certain line inside a $(...):

command:

$(sed -n '3p' script.sh)

It will print foo in bash your current shell.

share|improve this answer
    
@ormaaj: I agree with you in discouraging such a concept. On the other hand it comes handy when following instructions from a simple diary (log) file. –  fheub Jul 13 '12 at 9:49
    
I agree, this is exactly why am I using it. –  Vladimir Perković Jul 13 '12 at 9:55
1  
@fheub: This isn't a good answer because the argument list is built by word-splitting, with pathname expansion enabled. This will fail in all but simple cases. Always quote command substitutions. kev's answer is ok. Mine works in either a child process or the current environment because of the eval (and uses properly escaped input). If you have GNU sed available, a shell command can be executed in pure sed using the e function: sed -n $'3{e\np;q}' file –  ormaaj Jul 13 '12 at 10:15
    
@ormaaj: Touché! But Vladimir seems to be looking for a KISS-solution. –  fheub Jul 13 '12 at 10:27

script.sh

echo hello
echo world
echo foo
echo bar

command:

sed -n '3p' script.sh | bash

It will print foo

share|improve this answer
    
I think you should pipe to bash as Vladimir wants to execute the line. –  Bernhard Jul 13 '12 at 7:27

If you are talking about a shell script, you could do that like in this example:

#!/bin/bash
LINE='less'
#...
LINE="$LINE myfile.txt"
# now we execute that:
$LINE

Another example includes capturing the output for further processing:

#!/bin/bash
LINE="grep foo bar.txt"
OUTPUT=$($LINE)

In the second example, the variable $OUTPUT then contains the results of the executed grep command.

share|improve this answer

Probably not quite what you want, but could be useful to mention:

history -r script.sh

This reads each line of the script into your history list, from which you can execute any line using bash's history expansion feature.


A few failed attempts at reading in just the line you want to execute:

# No command substitution; the argument is added literally
history -s $(sed -n '3p' script.sh)

# Can't seem to read from stdin or from a process substitution
sed -n '3p' script.sh | history -r -
sed -n '3p' script.sh | history -r /dev/stdin
history -r <( sed -n '3p' script.sh )
share|improve this answer

You could but probably shouldn't. Create a library containing functions and source it. This is a very unusual requirement. Bash has actual means of control flow - there's no need to grab strings of code out of files to execute. This can be dangerous.

Here's a "toy" example, not for production use...

#!/usr/bin/env bash

shopt -s extglob

# evalLine filepath line-number
evalLine() {
    [[ -f $1 && $2 == +([[:digit:]]) ]] || return 1
    local x
    # This subtraction compensates for a bug that's since been fixed in 4.2.35 
    mapfile -ts $(($2 - 1)) -n 1 x &&
    ${x:+eval "$x"}
} <"$1"

evalLine /dev/stdin "$1" <<"EOF"
echo "line 1"
f() { echo "$1"; }; f "line 2"
var3='line 3' eval 'echo "$var3"'
EOF

Late edit: Note the comment regarding a bug in mapfile.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.