bashやzshでsudoを使う際、aliasは-Eでsudoに渡せるがfunctionは渡すことができない。 sudo自体にはfunctionを引き継がせるようなオプションは無く、そのままでは定義しているfunctionはsudoで実行させることができない。 じゃあどうするかというと、基本的には別途そのためのfunctionを別に設定してやり、それをsudoのaliasとして定義してやる。 以下、設定のサンプル。
function SudoFunc() {
local CMD=${1} # 実行コマンドを取得する
# 実行コマンドのタイプを取得する
case $(basename ${SHELL}) in
zsh*)
local TYPE=$(whence -w ${CMD}|cut -d" " -f 2)
;;
bash*)
local TYPE=$(type -t ${CMD})
;;
esac
# 実行するコマンドがaliasだった場合、aliasの第一引数を取得する
if [ ${TYPE} = "alias" ];then
local ALIAS=$(alias ${CMD})
local ORG_CMD=$(alias ${CMD} | sed -r "s/^alias .*='//;s/'$//g" | cut -d " " -f 1)
# ${TYPE}を上書き
case $(basename ${SHELL}) in
zsh*)
local TYPE=$(whence -w ${ORG_CMD}|cut -d" " -f 2)
;;
bash*)
local TYPE=$(type -t ${ORG_CMD})
;;
esac
else
local ORG_CMD=${CMD}
fi
# TYPEをチェックし、functionだった場合はsudoで実行する
# ※ sudoはエイリアスを読まないようにする
if [ ${TYPE} = "function" ];then
case ${OSTYPE} in
darwin*)
local DATA=$(base64 <(echo function "$(declare -f ${ORG_CMD})";echo ${ORG_CMD} ${@:2}))
\sudo -E ${SHELL} -c "$(echo ${DATA}|base64 -D)"
;;
linux*)
local DATA=$(base64 -w 0 <(echo function "$(declare -f ${ORG_CMD})";echo ${ORG_CMD} ${@:2}))
\sudo -E ${SHELL} -c "$(echo ${DATA}|base64 -d)"
esac
else
\sudo -E "$@"
fi
}
alias sudo='SudoFunc '
zshかbashか、LinuxかMacかで微妙に動きが異なるため、ちょこちょこcaseで分岐させている。一応、これでaliasに指定しているfunctionも対応できる(はず…)。 いつか、普通に何も考えずにsudoでfunctionを渡せるようになればいいのだけれど・・・(´・ω・`)。