Я пытаюсь выполнить конкретную строку текстового файла в Bash. Мне было интересно, возможно ли это сделать, не копируя эту строку в новый файл и не выполняя ее?
5 ответов
Опираясь на ответ @ kev (без связи с новым bash
): возьмите его скрипт
script.sh
echo hello
echo world
echo foo
echo bar
и выполнить определенную строку внутри $(...)
:
команда:
$(sed -n '3p' script.sh)
Он напечатает foo
в bash вашей текущей оболочки.
script.sh
echo hello
echo world
echo foo
echo bar
команда:
sed -n '3p' script.sh | bash
Это будет печатать foo
Вы могли бы, но, вероятно, не должны. Создайте библиотеку, содержащую функции, и получите ее. Это очень необычное требование. Bash имеет реальные средства управления потоком - нет необходимости извлекать строки кода из файлов для выполнения. Это может быть опасно.
Вот "игрушечный" пример, а не для производственного использования ...
#!/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
Позднее редактирование: обратите внимание на комментарий об ошибке в mapfile
.
Если вы говорите о сценарии оболочки, вы можете сделать это, как в этом примере:
#!/bin/bash
LINE='less'
#...
LINE="$LINE myfile.txt"
# now we execute that:
$LINE
Другой пример включает захват выходных данных для дальнейшей обработки:
#!/bin/bash
LINE="grep foo bar.txt"
OUTPUT=$($LINE)
Во втором примере переменная $OUTPUT
содержит результаты выполненной команды grep
.
Вероятно, не совсем то, что вы хотите, но может быть полезно упомянуть:
history -r script.sh
Это считывает каждую строку скрипта в ваш список истории, из которого вы можете выполнить любую строку, используя функцию расширения истории bash
.
Несколько неудачных попыток чтения только в той строке, которую вы хотите выполнить:
# 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 )