2

Я пытаюсь выполнить конкретную строку текстового файла в Bash. Мне было интересно, возможно ли это сделать, не копируя эту строку в новый файл и не выполняя ее?

5 ответов5

4

Опираясь на ответ @ kev (без связи с новым bash): возьмите его скрипт

script.sh

echo hello
echo world
echo foo
echo bar

и выполнить определенную строку внутри $(...):

команда:

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

Он напечатает foo в bash вашей текущей оболочки.

2

script.sh

echo hello
echo world
echo foo
echo bar

команда:

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

Это будет печатать foo

1

Вы могли бы, но, вероятно, не должны. Создайте библиотеку, содержащую функции, и получите ее. Это очень необычное требование. 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 .

1

Если вы говорите о сценарии оболочки, вы можете сделать это, как в этом примере:

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

Другой пример включает захват выходных данных для дальнейшей обработки:

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

Во втором примере переменная $OUTPUT содержит результаты выполненной команды grep .

1

Вероятно, не совсем то, что вы хотите, но может быть полезно упомянуть:

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 )

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .