起因
部署springboot項目時,為了保證他后他運行,我用了如下命令:
nohup java -jar jsczams-web-ams.jar > ams.log 2>&1 &
下面記錄nohup以及&的具體含義
&
一條命令后面跟個&表示該程序讓出終端,不占用終端,獨自后台運行。如果用下面的命令
java -jar jsczams-web-ams.jar &
表示我的程序后台運行,我可以用終端發出其他指令,做其他的事。
但是問題在於,如果我斷開終端(比如 ssh),而該程序屬於我這個會話的進程,也會被終斷。
由此可見,單獨使用&並不能滿足我們的需求。
nohup
當我們使用nohup命令時
nohup java -jar jsczams-web-ams
程序會繼續霸占終端,我們做不了其他的事,但是我們可以關閉這個終端,再開一個新的終端,這樣做並不會終止這個進程。但是新開一個終端有點麻煩,所以使用了下面的做法。
nohup和&
一般來說,nohup 和 & 都是結合起來使用的。表示程序后台運行,不占用當前終端,而且終端關閉后,程序還能繼續運行。
>和>>
這個應該比較簡單
>表示覆蓋指定文件,文件已有的內容都沒有了。
>>表示在文件的尾部追加內容。
2>&1的具體含義
這些數字是文件描述符,0表示標准輸入,1表示標准輸出,2表示標准錯誤輸出。
2>&1表示將標准錯誤輸出與標准輸出合並起來,也就是說將控制的所有輸出重定向到指定的文件里。
至於為什么是2>&1,而不是2>1,是因為2>1會被解釋為向1里面寫東西。
總結
現在再看這條指令的含義就很明確了
nohup java -jar jsczams-web-ams.jar > ams.log 2>&1 &
nohup 和 &保證能后台運行,>ams.log 將1的輸出重定向到ams.log文件,2>&1表示將2的輸出重定向給1,而此時1的輸出重定向到了ams.log,所以2和1的輸出都重定向到了ams.log文件中。
后續程序如果遇到什么問題,可以在程序所在目錄的ams.log文件中查到問題所在(tail命令)
如果嫌棄上面的寫法太繁瑣,也可以簡寫:
nohup java -jar jsczams-web-ams.jar &>ams.log &
或者
nohup java -jar jsczams-web-ams.jar >&ams.log &
補充
腳本
——————2020年11月9日補充——————
每次都輸這么長的命令,不免有些繁瑣,我們可以把它寫進腳本。
新建文件boot.sh
#! /bin/bash boot=$1 log=$2 if [ -z "$boot" ]; then echo "尚未指定jar包路徑" exit fi if [ -z "$log" ]; then echo "尚未指定日志存放目錄" exit fi nohup java -jar ${boot} > ${log} 2>&1 & echo 'sprinboot project start successfully'
運行
sh boot.sh 程序路徑 日志路徑
可以用相對路徑,也可以絕對路徑,只要定位到對應文件即可,例如:
我的腳本和程序在同一目錄:
sh boot.sh jsczams-web-ams.jar ams.log