我需要在處理來自模板的 Calc 電子表格的 Web 服務器上啟動無頭 LibreOffice。我嘗試使用以下命令在 Python 中直接執行此操作。
# Doesn't work as expected, no socket connection, "--accept ..." is ignored.
subprocess.Popen(['libreoffice', '--calc','--headless',
'--accept="socket,host=localhost,port=2002;urp;"','&'], shell=True)
但是,當我從 Python 啟動 Shell 腳本時,一切正常。
subprocess.call('/var/www/scripts/service_report_ods_prepare.sh', shell=True)
外殼腳本:
#!/bin/bash
app="soffice"
app_pid=`ps -ef | grep "$app" | awk '{print $2}'`
if `ps -p $app_pid > /dev/null`; then
echo "An instance of LibreOffice is running, pid = "$app_pid
echo "Not starting another instance."
else
libreoffice --headless --accept="socket,host=localhost,port=2002;urp;"& > /dev/null 2>&1
fi
我的 Python 代碼有什么問題?提前致謝。
uj5u.com熱心網友回復:
TL; 博士
做一個如下:
- 洗掉
shell=True(使用shell=False) - 將整個命令列放入一個字串中并使用它代替陣列:
subprocess.Popen('libreoffice --calc ...', shell=True)。確保正確轉義命令。 - 把整個命令列到第一和唯一的元素的
args。確保正確轉義命令。 - 修改第一個引數,使其接受位置引數,例如:
'libreoffice "$@"',其中"$@"擴展為位置引數的參考串列。
subprocess.Popen狀態檔案:
在 POSIX 上
shell=True,shell 默認為/bin/sh. 如果args是字串,則字串指定要通過 shell 執行的命令。這意味著字串的格式必須與在 shell 提示符下鍵入時完全相同。例如,這包括參考或反斜杠轉義其中包含空格的檔案名。如果args是序列,則第一項指定命令字串,任何附加項都將被視為 shell 本身的附加引數。也就是說,Popen 的作用相當于:Popen(['/bin/sh', '-c', args[0], args[1], ...])
因此,以下代碼:
subprocess.Popen(['libreoffice', '--calc','--headless',
'--accept="socket,host=localhost,port=2002;urp;"','&'], shell=True)
相當于 POSIX 上的以下 shell 命令:
/bin/sh -c libreoffice --calc --headless --accept="socket,host=localhost,port=2002;urp;" &
它實際運行libreoffice 腳本并將其余的引數 ( --calc,--headless等) 作為$0( --calc), $1( --headless) 等傳遞給這個“腳本” 。但位置引數從未在腳本中使用,所以代碼實際上只運行libreoffice命令。
請參閱sh( man sh)的手冊頁:
-c 如果存在 -c 選項,則從第一個非選項引數 command_string 讀取命令。如果在 command_string 之后有引數,則第一個引數被分配給 $0,任何剩余的引數都分配給位置引數。對 $0 的賦值設定了 shell 的名稱,該名稱用于警告和錯誤訊息。
uj5u.com熱心網友回復:
非常感謝大家的幫助!這成功了。
subprocess.Popen(['libreoffice', '--calc', '--headless',
'--norestore', '--nofirststartwizard', '--nologo',
'--accept="socket,host=localhost,port=2002;urp;"'], shell=False)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/333146.html
上一篇:如何在bashfor回圈中以給定前綴開頭的CMake生成的Makefile中編譯所有目標的子集
下一篇:在shell腳本中呼叫鏈碼函式
