How to run a shell script in background?
If that is not what you are after, please be more specific in your question.
What if I for example need to run 2 scipts and then I want to run htop to see CPU usage, but problem is that 1st script start to create output to console and it seems prevent other actions(run second script, run htop ).
I had to use nohup to prevent a script (executed with & ) that I had to bg from halting for some reason.
If you want the script to remain after closing the terminal, another option is to use setsid :
For more information about the differences between nohup , disown , & and setsid : Difference between nohup, disown and &
you can just switch screen and run your script on that 2nd screen. When script started on 2nd, switch back to 1st and do whatever you want. 2nd screen will be in the background as extra «terminal window». and it will not stop processing even when you close your ssh connection while beeing at 1st screen.
screen --help Use: screen [-opts] [cmd [args]] or: screen -r [host.tty] Options: -4 Resolve hostnames only to IPv4 addresses. -6 Resolve hostnames only to IPv6 addresses. -a Force all capabilities into each window's termcap. -A -[r|R] Adapt all windows to the new display width & height. -c file Read configuration file instead of '.screenrc'. -d (-r) Detach the elsewhere running screen (and reattach here). -dmS name Start as daemon: Screen session in detached mode. -D (-r) Detach and logout remote (and reattach here). -D -RR Do whatever is needed to get a screen session. -e xy Change command characters. -f Flow control on, -fn = off, -fa = auto. -h lines Set the size of the scrollback history buffer. -i Interrupt output sooner when flow control is on. -l Login mode on (update /var/run/utmp), -ln = off. -ls [match] or -list. Do nothing, just list our SockDir [on possible matches]. -L Turn on output logging. -m ignore $STY variable, do create a new screen session. -O Choose optimal output rather than exact vt100 emulation. -p window Preselect the named window if it exists. -q Quiet startup. Exits with non-zero return code if unsuccessful. -r [session] Reattach to a detached screen process. -R Reattach if possible, otherwise start a new session. -s shell Shell to execute rather than $SHELL. -S sockname Name this session .sockname instead of ... -t title Set title. (window's name). -T term Use term as $TERM for windows, rather than "screen". -U Tell screen to use UTF-8 encoding. -v Print "Screen version 4.01.00devel (GNU) 2-May-06". -wipe [match] Do nothing, just clean up SockDir [on possible matches]. -x Attach to a not detached screen. (Multi display mode). -X Execute as a screen command in the specified session.
ctrl + a , c will create a new «window» in your active screen session. You can switch between multiple windows (as Ansgar indicated) with ctrl + a , n for the next window, and ctrl + a , p for the previous window.
ctrl + a , » will give you a list of all your open windows.
Запуск скриптов в фоновом режиме
Для возможности выполнения bash-подобных скриптов в Linux в с целом и в OpenWrt-версии оболочки busybox в частности существует легкая в применении инфраструктура: необходимо лишь добавить к строке запускаемого скрипта символ “&“. Но есть и менее очевидные частности.
Реализация простого запуска некоторого скрипта /srv/tools/script.sh в фоне:
Все бы хорошо, но запущенный таким образом скрипт проработает ровно до тех пор, пока вы залогинены на консоль сервера. При отключении от сервера скрипт автоматически завершится.
Для запуска скрипта без связи с сессией пользователя следует использовать утилиту nohup:
В этом случае запущенный скрипт останется работать даже при отключении от сервера, но весь выводимый скриптом текст будет записываться в файл nohup.log, создаваемый в текущем каталоге, о чем nohup непосредственно и информирует сообщением nohup: appending output to nohup.out. При этом данный файл будет создан даже в том случае, если у скрипта никогда не будет никакого вывода.
Чтобы nohup.log никогда не создавался, перенаправляем stdout скрипта в /dev/null:
nohup /srv/tools/netstat.sh >/dev/null &
Все, теперь лишних файлов более не создается и скрипт останется работать при отключении от консоли.
Интересно отметить, что при автоматическом запуске скриптов из /etc/rc.local при загрузке системы не требуется использовать ни перенаправление вывода, ни nohup – достаточно одного лишь символа &.
executing shell command in background from script [duplicate]
how can I execute a shell command in the background from within a bash script, if the command is in a string? For example:
#!/bin/bash cmd="nohup mycommand"; other_cmd="nohup othercommand"; "$cmd &"; "$othercmd &";
4 Answers 4
nicholas@nick-win7 /tmp $ cat test #!/bin/bash cmd="ls -la" $cmd & nicholas@nick-win7 /tmp $ ./test nicholas@nick-win7 /tmp $ total 6 drwxrwxrwt+ 1 nicholas root 0 2010-09-10 20:44 . drwxr-xr-x+ 1 nicholas root 4096 2010-09-10 14:40 .. -rwxrwxrwx 1 nicholas None 35 2010-09-10 20:44 test -rwxr-xr-x 1 nicholas None 41 2010-09-10 20:43 test~
Also make sure you do not put quotations around $cmd . If you do, it will try to run a command called «ls -la» instead of ls with the switches -la .
cmd=’some-command «with arguments»‘; $cmd is not at all the same as some-command «with arguments» . It’ll fail if you have quoting in your argument list; it’ll fail if you need to control when globs are and are not expanded; it’ll fail if running code that depends on brace expansion or parameter expansion at execution time. See BashFAQ #50: I’m trying to put a command in a variable, but complex cases always fail!.
Building off of ngoozeff ‘s answer, if you want to make a command run completely in the background (i.e., if you want to hide its output and prevent it from being killed when you close its Terminal window), you can do this instead:
- &>/dev/null sets the command’s stdout and stderr to /dev/null instead of inheriting them from the parent process.
- & makes the shell run the command in the background.
- disown removes the “current” job, last one stopped or put in the background, from under the shell’s job control.
In some shells you can also use &! instead of & disown ; they both have the same effect. Bash doesn’t support &! , though.
Also, when putting a command inside of a variable, it’s more proper to use eval «$» rather than «$» :
If you run this command directly in Terminal, it will show the PID of the process which the command starts. But inside of a shell script, no output will be shown.
#!/bin/bash # Run a command in the background. _evalBg() < eval "$@" &>/dev/null & disown; > cmd="google-chrome"; _evalBg "$";
Как запустить процесс в фоне Linux
Как правило, выполнение команд в терминале связано с одним неудобством — прежде чем приступить к вводу следующей команды, следует дождаться выполнения предыдущей. Это происходит, поскольку текущий процесс блокирует доступ к оболочке операционной системы и в таких случаях говорят, что команда выполняется на переднем плане. Что же делать, если нужно запустить несколько команд одновременно? Есть несколько решений. Первое и наиболее очевидное — открыть дополнительное окно терминала. Второе — инициировать выполнение команды в фоновом режиме.
Если какой-либо процесс происходит в фоновом режиме, это значит, что он не предусматривает взаимодействия с пользователем, следовательно, доступ к оболочке остается свободным. Прочитав эту статью, вы узнаете как запустить процесс в фоне Linux и что делать, чтобы их выполнение не прерывалось после закрытия терминала.
Как запустить процесс в фоне Linux
Для выполнения команды в фоновом режиме достаточно добавить в конце символ амперсанда (&):
В выводе терминала будут отображены порядковый номер задачи (в квадратных скобках) и идентификатор процесса:
В фоновом режиме можно одновременно запускать сразу два, три, четыре процесса и даже больше.
Работая в фоновом режиме, команда все равно продолжает выводить сообщения в терминал, из которого была запущена. Для этого она использует потоки stdout и stderr, которые можно закрыть при помощи следующего синтаксиса:
Здесь >/dev/null 2>&1 обозначает, что stdout будет перенаправлен на /dev/null, а stderr — к stdout.
Узнать состояние всех остановленных и выполняемых в фоновом режиме задач в рамках текущей сессии терминала можно при помощи утилиты jobs c использованием опции -l:
Вывод содержит порядковый номер задачи, идентификатор фонового процесса, состояние задачи и название команды, которая запустила задание.
В любое время можно вернуть процесс из фонового режима на передний план. Для этого служит команда fg:
Если в фоновом режиме выполняется несколько программ, следует также указывать номер. Например:
Для завершения фонового процесса применяют команду kill с номером программы:
Как перевести процесс в фоновый режим
Если изначально процесс был запущен обычным способом, его можно перевести в фоновый режим, выполнив следующие действия:
- Остановить выполнение команды, нажав комбинацию клавиш Ctrl+Z.
- Перевести процесс в фоновый режим при помощи команды bg.
Работа процессов в фоне
Запуск скрипта в фоне linux — это одно, но надо чтобы он ещё работал после закрытия терминала. Закрытие терминала путем нажатия на крестик в верхнем углу экрана влечет за собой завершение всех фоновых процессов. Впрочем, есть несколько способов сохранить их после того как связь с интерактивной оболочкой прервется. Первый способ — это удаление задачи из очереди заданий при помощи команды disown:
Как и в предыдущих случаях, при наличии нескольких одновременно выполняемых процессов следует указывать номер того, относительно которого будет выполнено действие:
Убедиться, что задачи больше нет в списке заданий, можно, использовав уже знакомую утилиту jobs -l. А чтобы просмотреть перечень всех запущенных процессов (в том числе и отключенных) применяется команда
Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Она выполняет другую команду, которая была указана в качестве аргумента, при этом игнорирует все сигналы SIGHUP (те, которые получает процесс при закрытии терминала). Для запуска команды в фоновом режиме нужно написать команду в виде:
Как видно на скриншоте, вывод команды перенаправляется в файл nohup.out. При этом после выхода из системы или закрытия терминала процесс не завершается. Существует ряд программ, которые позволяют запускать несколько интерактивных сессий одновременно. Наиболее популярные из них — Screen и Tmux.
- Screen либо GNU Screen — это терминальный мультиплексор, который позволяет запустить один рабочий сеанс и в рамках него открыть любое количество окон (виртуальных терминалов). Процессы, запущенные в этой программе, будут выполняться, даже если их окна невидимы или программа прекратила работу.
- Tmux — более современная альтернатива GNU Screen. Впрочем, возможности Tmux не имеют принципиальных отличий — в этой программе точно так же можно открывать множество окон в рамках одного сеанса. Задачи, запущенные в Tmux, продолжают выполняться, если терминал был закрыт.
Выводы
Чтобы запустить скрипт в фоне linux, достаточно добавить в конце знак &. При запуске команд в фоновом режиме отпадает необходимость дожидаться завершения одной команды для того, чтобы ввести другую. Если у вас возникли вопросы, обязательно задавайте их в комментариях.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.