Число новых строк в строке как целое [дубликат]

Когда процесс завершается, PPID его дочерних процессов устанавливается в 1 (принятие init), но PGID (идентификатор группы процессов) и SID (идентификатор сессии) не изменяются.

Дочерние процессы, вероятно, не меняют свою группу процессов, если только они не предназначены быть демонами. Если это не так, запустите тестируемый процесс в его собственной группе процессов. Вызовите setpgid(getpid(), getpid()) из вашего тестового фреймворка, после форка и перед вызовом execve для выполнения тестируемой программы. Вызовите kill(-test_program_pid, 0) (kill с отрицательным аргументом pid и значением сигнала 0), чтобы проверить, существует ли запущенный процесс с PGID test_program_pid. Передайте SIGKILL в качестве аргумента сигнала, чтобы убить их всех.

test_program_pid = fork();
if (test_program_pid) {
    waitpid(test_program_pid, &status, 0);
    if (kill(-test_program_pid, 0)) {
        record_failue("some child processes were not terminated properly");
    }
    kill(-test_program_pid, SIGKILL);
} else {
    setpgid(getpid(), getpid());
    execve("/program/to/test", …);
}

Альтернативным методом может быть создание временного файла и открытие его в программе, которую вы тестируете, и нигде больше. Если программа вызывает execve, убедитесь, что дескриптор файла открыт без флага O_CLOEXEC (или вызовите fcntl(fd, FD_CLOEXEC, 0)). Этот метод предполагает, что программа не идет и не закрывает файловые дескрипторы, которые она явно не использует. Затем вы можете выполнить fuser /temp/file, чтобы перечислить процессы, у которых открыт этот файл, и fuser -k /temp/file, чтобы убить их. Вариант этого подхода, который работает даже с программами, закрывающими неиспользуемые дескрипторы файлов, но предполагает, что программа не меняет свой текущий каталог, заключается в создании временного каталога и переходе в этот каталог для запуска программы.

3
12.03.2017, 07:26
3 ответа

Хотя я не совсем понимаю , зачем вам это , это один из способов сделать это. Ключом является $ () для захвата вывода и присвоения его переменной.

Код:

#!/usr/bin/env bash
IFS='' read -r -d '' TEST_STR <<-'EOF'
    Test text
    quick brown fox
    lazy dog
EOF

NEW_LINE_COUNT=$(echo "$TEST_STR" | wc -l)

echo "$TEST_STR"
echo "$NEW_LINE_COUNT"

Результаты:

Test text
quick brown fox
lazy dog

4
3
27.01.2020, 21:12

Если у вас многострочная строка, вы можете просто использовать wc -l для подсчета количества строк в нем:

printf '%s' "$string" | wc -l

Чтобы сохранить это число в переменной:

nlines=$( printf '%s' "$string" | wc -l )

Однако вам не нужно это число для выполнения цикла while:

printf '%s' "$string" |
while read -r line; do
   # do something with "$line"
done

В зависимости от в зависимости от того, что вы делаете с каждой строкой, вам может вообще не понадобиться цикл while:

printf '%s' "$string" | awk '<some awk script>'

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

some_command | some_line_by_line_processing

Здесь some_command может быть циклом while, набором команд в подоболочке ( (...) ) или простой командой, которая генерирует вывод и some_line_by_line_processing аналогичным образом может быть простой командой (например, awk ) или циклом или чем-то еще, что вам нужно для обработки вывода первой части конвейера построчно.

2
27.01.2020, 21:12

Вам не нужно подсчитывать строки в многострочной строке, чтобы просмотреть отдельные устройства. Цикл for в тандеме с переменными массива можно использовать здесь следующим образом:

IFS=$'\n' read -d '' -r -a Multi_Line_Str <<STR
    $(printf '%s\n' 'device_'{A..E})
STR

for device in "${Multi_Line_Str[@]}"
do
    echo "<$device>"
done
2
27.01.2020, 21:12

Теги

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