Как выйти из сценария bash, если корневая оболочка находится в активном процессе

Вы, кажется, неправильно понимаете, как sedработает --при запуске команды sed для файла, она читает весь файл и применяет правила редактирования к каждой строке (, если только в правилах есть строка «адрес», которая ограничивает их применение ). Итак, в вашем примере вы начинаете с файла, в котором всего три пустые строки, и запускаете на нем sed -i -e "i\input $fieldname ", он добавляет строку, в которой говорится, например. "введите abc" перед каждой из этих трех строк . Таким образом, у вас есть файл, который выглядит так:

input abc 

input abc 

input abc 

(Его не видно, но в конце есть пустая строка. )Их, вы запускаете sed -i -e 's/^/ /', и он добавляет четыре пробела перед каждой строкой (, включая пустые):

    input abc 

    input abc 

    input abc 

Затем вы запускаете sed -i '/^[[:space:]]*$/d', что на самом деле делает то, что вы ожидаете --он удаляет строки, содержащие только пробелы, оставляя:

    input abc 
    input abc 
    input abc 

Затем, в следующей итерации цикла, вы запускаете sed -i -e "i\input def ", что снова помещает эту новую строку перед каждой из существующих строк:

input def 
    input abc 
input def 
    input abc 
input def 
    input abc 

А затем sed -i -e 's/^/ /'снова добавляет 4 пробела к каждой строке (, включая те, в которых уже есть пробелы):

    input def 
        input abc 
    input def 
        input abc 
    input def 
        input abc 

...и т.д. Это совсем не то, что вы хотите .

Насколько я понимаю, что вы пытаетесь сделать, sedдействительно не подходит для этой работы.Вместо того, чтобы пытаться отредактировать существующий файл, вы, кажется, хотите просто создать новый файл, добавив в него строку -на строку -. Вы можете сделать это довольно легко вот так:

: >"$FILES"    # This empties the file (in case there's something there from last run)

I=0
for fieldname in $value
do
    echo "Line number $((I++)) --> $fieldname"
    echo "    input $fieldname" >>"$FILES"    # Append a line to the end of the file
done

Если вам не нужно печатать «Номер строки...» или вы можете отправить его на стандартный вывод ошибок вместо стандартного вывода (, куда обычно следует отправлять информацию о состоянии, даже если она не настоящие ошибки ), можно сделать еще проще:

I=0
for fieldname in $value
do
    echo "Line number $((I++)) --> $fieldname" >&2    # The >&2 redirects to standard error
    echo "    input $fieldname"
done >"$FILES"    # Just send *all* standard output from the loop into the file

В обоих случаях для предварительной загрузки файла не требуется ни num, ни выходные данные yes.

Здесь есть куча других вещей, которые выглядят как плохие практики. Во-первых, ссылки на переменные почти всегда должны заключаться в двойные -кавычки, как "$FILES"в моих примерах выше. Это предотвращает их неожиданное разделение на несколько «слов» и/или расширение в виде подстановочных знаков имени файла. Я рекомендую shellcheck.net для указания на распространенные ошибки, подобные этой.

Обратите внимание, что я не делал этого с $value(for fieldname in $value), потому что в этом случае вы зависите от оболочки, разбивающей значение переменной на слова... что не особенно безопасно. Вы действительно хотите перебрать слов во входном файле или вместо этого хотите перебрать строк ? Если вам нужны линии, не используйте эту конструкцию for... in, используйте цикл read:

I=0
while read fieldname
do
    echo "Line number $((I++)) --> $fieldname" >&2
    echo "    input $fieldname"
done <"$FILE1" >"$FILES"    # Read input from $FILE1, write output to $FILES

См. BashFAQ #001 :«Как я могу прочитать файл (поток данных, переменную )строку -по -строку (и/или поле -полем -)?" для получения дополнительной информации.

Как отметил @Kusalananda в (теперь -удаленном )комментарии, если вы выполняете эту строку -по строке -и вам не нужен "Номер строки..." вывод вообще, вы можете сделать это с помощью sed. Но не в панцирной петле,просто позволив sedсамому сканировать входной файл, добавляя «input» к каждой строке по мере продвижения:

sed 's/^/    input /' "$FILE1" >"$FILES"

В любом случае, сейчас вы копируете $FILE1 в файл с буквальным именем "FILE2", затем читаете его в переменную с именем value... и ничего из этого не требуется; все, что вы делаете, должно просто читаться непосредственно из исходного файла.

В другом примечании :используются имена переменных нижнего -или смешанного -регистра вместо всех имен -заглавными буквами. Существует множество имен -с заглавными буквами, которые имеют особое значение для оболочки и/или других инструментов, и если вы используете одно из них по ошибке, могут произойти странные вещи.

0
27.11.2018, 23:17
1 ответ

Запустите which swapoffи which swaponи используйте в сценарии полный путь. Или обновите PATHenv в начале скрипта и добавьте в него каталог, содержащий эти двоичные файлы.

0
28.01.2020, 04:07

Теги

Похожие вопросы