bash-4.1$ ps -ef|grep component_events.xml
gdxx1122 1190 1181 0 Mar25 ? 00:00:00 /xx1122/fmw/product/111/ohs_111/ohs/bin/odl_rotatelogs -l -h:/xx1122/admin/xx1122_vmabcd123/config/OHS/ohs1/component_events.xml_ohs1
/xx1122/admin/xx1122_vmabcd123/auditlogs/OHS/ohs1/audit-pid1181-%Y%m%d%H%M%S.log 1M 4M
gdxx1122 19885 19205 0 08:05 pts/1 00:00:00 grep component_events.xml
上記のコマンドをスクリプトで実行すると、「/xx1122/admin/xx1122_vmabcd123/config/OHS/ohs1」が抽出され、変数に割り当てられます。上記の出力はサーバーごとに異なる可能性があるため、動的でなければなりません。開始文字列xx1122は動的に渡されなければなりません。
答え1
POSIXlyを使用してくださいsed
:
var=$(
ps -Ao args= | sed -n 's|.* -h:\(.*\)/component_events\.xml.*|\1|p'
)
/component_events.xml
実際、これは最後の発生と前の最後の発生の間のコマンドライン部分を返します-h:
。
したがって、コマンドラインが次のような場合:
... -h:x/component_events.xml -g:y/component_events.xml
x/components_events.xml -g:y
あなたは代わりに得るでしょうx
。
これを防ぐために変更できますが、sed -n 's|.* -h:\([^ ]*\)/component_events\.xml.*|\1|p'
スペース文字を含むディレクトリ名には機能しません。
最新のGNU / Linuxシステムでは、次のこともできます。
LC_ALL=C grep -zhPo '^-h:\K.*(?=/component_events\.xml)' /proc/*/cmdline |
tr '\0' '\n'
これはすべてのディレクトリ名に適用されます。
答え2
pgrep
pidを見つけるために使用されます/proc/$PID/cmdline
。
var=$(
pgrep -f "component_events.xml" | \
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline | tr '\0' '\n'" | \
xargs -n1 dirname
)
これは、コマンドパスにパラメータがあり、複数のPIDが見つかった場合にも機能します。
説明する:
検索PID:
pgrep -f "component_events.xml"
見つかった各PIDに対して完全なコマンド(/proc/PID/cmdline
)を取得しますが、引数()なしでコマンドのみを印刷しますhead -z -n1
。
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline
次に、末尾の\0
改行文字(\n
)を置き換えます。
tr '\0' '\n'"
ディレクトリ名のみ出力:
xargs -n1 dirname