私は現在私の機能を書こうとしています。バッシュ構成ファイルこれにより、OSX LaunchAgentが引数として渡され、再起動されます。やや無意味かもしれませんが、私には長いパスを書きたくありません。launchctl un/load
私はlaunchctlの最後の呼び出しを除いて、ほとんどすべてのことをしました。以下は、関数スクリプトとそれに続くエラーメッセージです。
機能
launchctl_mgr() {
failure() {
local lineno=$1
local msg=$2
echo "Failed at $lineno: $msg"
}
trap 'failure ${lineno} "$BASH_COMMAND"' ERR
trap 'trap - ERR' RETURN
instruction=$1
filepath=$2;
#test whether the file argument is already a file or not and whether or not it is actually$
if [[ ! -f $2 ]]
then
if [[ -f ~/Library/LaunchAgents/$2.plist ]]
then
filepath="~/Library/Launchagents/$filepath.plist"
echo "found!: $filepath"
elif [[ -f /Library/LaunchAgents/$2.plist ]]
then
filepath="/Library/LaunchAgents/$filepath.plist"
else
echo "debug: ~/Library/LaunchAgents/$filepath.plist"
echo "Filename supplied was not valid as a launchagent"
return 1
fi
fi
if [[ $instruction=="restart" || instruction=="unload" ]]
then
echo "instruction is $instruction"
echo "filepath is $filepath"
launchctl stop $filepath
launchctl unload $filepath
if [[ instruction=="restart" ]]
then
launchctl load $filepath
launchctl start $filepath
fi
fi
}
出力/エラー
____________________ => launchctl_mgr unload local.unminimise
found!: ~/Library/Launchagents/local.unminimise.plist
instruction is unload
filepath is ~/Library/Launchagents/local.unminimise.plist
Failed at launchctl stop $filepath:
/Users/[current_user]/~/Library/Launchagents/local.unminimise.plist: No such file or directory
/Users/[current_user]/~/Library/Launchagents/local.unminimise.plist: No such file or directory
Failed at launchctl start $filepath:
(「[current_user]」は実際のユーザーアカウント名を置き換えます)
launchctlが示すように、bashとlaunchctlの両方が現在のディレクトリパスとlaunchctlに入力したパス文字列を連結してエラーになります。ファイルパス文字列が印刷され、前の行では問題ありません。
答え1
[[...]]テストでは==前後にスペースが必要です。それ以外の場合は文字列として評価され、空でないことは常にtrueです。
たとえば、
$ instruction=whatever $ [[ $instruction=="restart" ]] && echo true || echo false true
これは次のとおりです。
$ [[ whatever=="restart" ]] && echo true || echo false true
また、以下と同じです(他のいくつかのバリエーションも含みます)。
$ [[ -n 'whatever=="restart"' ]] && echo true || echo false true
$instruction
これらすべての場合、「再起動」が同じであることを確認しません。代わりに文字列がwhatever=="restart"
空でないことをテストしています。文字列には文字の順序が正確に含まれていますが、==
これは重要ではありません。これは文字列に含まれる文字にすぎず、特別な意味はありません。比較:
$ instruction=whatever $ [[ $instruction == "restart" ]] && echo true || echo false false $ instruction=restart $ [[ $instruction == "restart" ]] && echo true || echo false true
スクリプトには
$
before変数が欠落している場所もあります。例えばif [[ $instruction=="restart" || instruction=="unload" ]]
先行および末尾のスペースが必要です。
==
そして$
2番目の前にainstruction
:if [[ $instruction == "restart" || $instruction == "unload" ]]
ここでも同様です。
if [[ instruction=="restart" ]]
これは次のようになります。
if [[ $instruction == "restart" ]]
変数(およびシェル位置パラメータ)を使用するときは、二重引用符で囲む必要があります。例えば
local lineno="$1" local msg="$2"
そして:
instruction="$1" filepath="$2"
そして:
launchctl stop "$filepath" launchctl unload "$filepath"
スタンドアロンスクリプトの代わりに関数で書くのはなぜですか?現在のシェルの環境を変更するために必要ですか?
関数を書くには問題はありませんが、考える現在のシェルの環境を変更したい場合は、誤って環境が変更されないように、別のスクリプトによって提供される分離機能を活用することをお勧めします。
またはステートメントみんな関数変数(
$instruction
および含む$filepath
)local
を変更しましたが、これは変数の変更を防ぐためにのみ機能し、関数はまだシェルの現在のディレクトリなどの他の項目を変更できます。
答え2
bashの構文に答えて助けてくれたCasに感謝します。しかし、いくつかの作業で知りました。ティルデinは、~/Library/LaunchAgents/[agent]
パス接続に問題を引き起こすのではなく、スクリプトが実際に期待どおりに機能するようにする原因です。
何らかの理由でlaunchctlアドレスパラメータでチルダが拡張されないため、他の人にこの問題がある場合は、次を使用してください。
$HOME/Library/LaunchAgents/[agent]
launchctlコマンドでエージェントのアドレスを指定します。
パスは説明通りですここ下に「前のコマンド」を押してから「ロード」
気づく:私のスクリプトでは、少なくともこれはlaunchctlの発生エラーを実際には修正していませんが、機能は修正しました。文書には次のように記載されています。
以前の実装のバグと、これらのバグに対する顧客の長期的な期待のため、ロードおよびアンロードサブコマンドは、不適切な使用のためにゼロ以外の終了コードのみを返します。それ以外の場合は常に0が返されます。
..スクリプトが期待どおりに機能し、手動コピーコマンドがエラーメッセージを表示しない場合でも、私が設定したERRトラップは常にメッセージなしでエラーを発生させます。
誰かが私の無知を補償してくれるかもしれませんが、私が提案した後もまだ頭痛が感じられる場合は、試してみてlaunchctl list | grep [agent_name]
欲しい効果が現れるかどうかを確認してください。