Начиная с ответа bmargulies , я написал функцию для освещения этой проблемы, которая в основном реализует его идею.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
# EXESUDO
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
#
# Purpose:
# -------------------------------------------------------------------- #
# Execute a function with sudo
#
# Params:
# -------------------------------------------------------------------- #
# $1: string: name of the function to be executed with sudo
#
# Usage:
# -------------------------------------------------------------------- #
# exesudo "funcname" followed by any param
#
# -------------------------------------------------------------------- #
# Created 01 September 2012 Last Modified 02 September 2012
function exesudo ()
{
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ##
#
# LOCAL VARIABLES:
#
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ##
#
# I use underscores to remember it's been passed
local _funcname_="$1"
local params=( "$@" ) ## array containing all params passed here
local tmpfile="/dev/shm/$RANDOM" ## temporary file
local filecontent ## content of the temporary file
local regex ## regular expression
local func ## function source
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ##
#
# MAIN CODE:
#
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ##
#
# WORKING ON PARAMS:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Shift the first param (which is the name of the function)
unset params[0] ## remove first element
# params=( "${params[@]}" ) ## repack array
#
# WORKING ON THE TEMPORARY FILE:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
content="#!/bin/bash\n\n"
#
# Write the params array
content="${content}params=(\n"
regex="\s+"
for param in "${params[@]}"
do
if [[ "$param" =~ $regex ]]
then
content="${content}\t\"${param}\"\n"
else
content="${content}\t${param}\n"
fi
done
content="$content)\n"
echo -e "$content" > "$tmpfile"
#
# Append the function source
echo "#$( type "$_funcname_" )" >> "$tmpfile"
#
# Append the call to the function
echo -e "\n$_funcname_ \"\${params[@]}\"\n" >> "$tmpfile"
#
# DONE: EXECUTE THE TEMPORARY FILE WITH SUDO
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sudo bash "$tmpfile"
rm "$tmpfile"
}
Пример использования:
запускает следующий фрагмент
#!/bin/bash
function exesudo ()
{
# copy here the previous exesudo function !!!
}
test_it_out ()
{
local params=( "$@" )
echo "Hello "$( whoami )"!"
echo "You passed the following params:"
printf "%s\n" "${params[@]}" ## print array
}
echo "1. calling without sudo"
test_it_out "first" "second"
echo ""
echo "2. calling with sudo"
exesudo test_it_out -n "john done" -s "done"
exit
Будет выводить
вызов без sudo
Здравствуйте, ваше имя!
Вы приняли следующие параметры:
первый
второй
звонит с sudo
Привет рут!
Вы приняли следующие параметры:
-n
Джон сделал
-s
Foo
Если вам нужно использовать это в оболочке, вызывающей функцию, которая определена в вашем bashrc, как это было задано с аналогичным вопросом о serverfault другим пользователем, то вы должны поместить предыдущую функцию exesudo в ту же * Файл 1046 * bashrc , например:
function yourfunc ()
{
echo "Hello "$( whoami )"!"
}
export -f yourfunc
function exesudo ()
{
# copy here
}
export -f exesudo
Затем вы должны выйти из системы и войти снова или использовать
source ~/.bashrc
Наконец, вы можете использовать exesudo следующим образом:
$ yourfunc
Hello yourname!
$ exesudo yourfunc
Hello root!