#bash #shell
#bash #оболочка
Вопрос:
Я выполнил фоновый процесс, который был получен в качестве параметра, и мне не удалось получить имя процесса после выполнения.
Я делаю следующее:
#! /bin/bash
filePath=$1
$filePath > log.txt amp;
echo `jobs -l`
Фактический результат:
[1] 2381 Running $filePath > log.txt amp;
Ожидаемый результат:
[1] 2381 Running /home/user/Desktop/script.sh > log.txt amp;
Комментарии:
1. Кстати, обратите внимание, что для того, чтобы shebang имел какой-либо эффект, он должен быть
#!/bin/bash
, а не!#/bin/bash
.2. Кстати, почему
echo
вообще?jobs -l
сам по себе записывает свой вывод в стандартный вывод, поэтому его захват, а затем повторная запись выглядят бессмысленными.
Ответ №1:
Лучший ответ — нет; управление заданиями — это функция, предназначенная для интерактивного использования, и не гарантируется, что она вообще будет доступна в неинтерактивных оболочках, а тем более гарантированно будет вести себя каким-либо полезным или значимым образом. Однако, если вы настаиваете, вы можете использовать printf %q
для генерации строки eval
-safe с формой ваших переменных после расширения, а затем использовать eval
для ее запуска в виде кода:
#!/bin/bash
printf -v logfile_q '%q' "${log:-log.txt}" # use "$logfile", or default to log.txt
printf -v cmd_q '%q ' "$@" # quote our arguments into one eval-safe string
eval "$cmd_str >$logfile_q amp;" # Parts that aren't hardcoded must be printf-q'd for safety.
jobs -l
Обратите внимание, что я добавил некоторую дополнительную настраиваемость ради демонстрации — это нормально иметь >log.txt
внутри вашего eval
общего кода, но это небезопасно >$logfile
, потому что если logfile=$'foo$(rm -rf ~)'$(rm -rf ~)''
(совершенно законное имя файла!), То вы потеряете свой домашний каталог. Таким образом, любые переменные, которые необходимо использовать внутри аргумента eval
, должны быть экранированы printf %q
заранее.
Комментарии:
1. Если вы не используете
printf %q
для создания ее аргумента, использованиеeval
создает серьезные риски для безопасности. См . BashFAQ # 48