मेरे पास एक वैश्विक bashrc में परिभाषित बैश फ़ंक्शन है, जिसे काम करने के लिए रूट विशेषाधिकार की आवश्यकता होती है। मैं इसे सुडो के साथ कैसे चला सकता हूं, जैसे sudo myfunction
। डिफ़ॉल्ट रूप से यह एक त्रुटि देता है:
sudo: myfunction: कमांड नहीं मिली
मेरे पास एक वैश्विक bashrc में परिभाषित बैश फ़ंक्शन है, जिसे काम करने के लिए रूट विशेषाधिकार की आवश्यकता होती है। मैं इसे सुडो के साथ कैसे चला सकता हूं, जैसे sudo myfunction
। डिफ़ॉल्ट रूप से यह एक त्रुटि देता है:
sudo: myfunction: कमांड नहीं मिली
जवाबों:
लुका ने कृपया मुझे इस प्रश्न की ओर इशारा किया, यहां मेरा दृष्टिकोण है: सूडो को कॉल करने से पहले फ़ंक्शन / उपनाम का विस्तार करें और इसे अपनी संपूर्णता में पारित करें सूडो को, किसी भी अस्थायी फ़ाइलों की आवश्यकता नहीं है।
मेरे ब्लॉग पर यहाँ बताया गया है । बोली से निपटने के बहुत सारे हैं :-)
# Wrap sudo to handle aliases and functions
# Wout.Mertens@gmail.com
#
# Accepts -x as well as regular sudo options: this expands variables as you not root
#
# Comments and improvements welcome
#
# Installing: source this from your .bashrc and set alias sudo=sudowrap
# You can also wrap it in a script that changes your terminal color, like so:
# function setclr() {
# local t=0
# SetTerminalStyle $1
# shift
# "$@"
# t=$?
# SetTerminalStyle default
# return $t
# }
# alias sudo="setclr sudo sudowrap"
# If SetTerminalStyle is a program that interfaces with your terminal to set its
# color.
# Note: This script only handles one layer of aliases/functions.
# If you prefer to call this function sudo, uncomment the following
# line which will make sure it can be called that
#typeset -f sudo >/dev/null && unset sudo
sudowrap ()
{
local c="" t="" parse=""
local -a opt
#parse sudo args
OPTIND=1
i=0
while getopts xVhlLvkKsHPSb:p:c:a:u: t; do
if [ "$t" = x ]; then
parse=true
else
opt[$i]="-$t"
let i++
if [ "$OPTARG" ]; then
opt[$i]="$OPTARG"
let i++
fi
fi
done
shift $(( $OPTIND - 1 ))
if [ $# -ge 1 ]; then
c="$1";
shift;
case $(type -t "$c") in
"")
echo No such command "$c"
return 127
;;
alias)
c="$(type "$c")"
# Strip "... is aliased to `...'"
c="${c#*\`}"
c="${c%\'}"
;;
function)
c="$(type "$c")"
# Strip first line
c="${c#* is a function}"
c="$c;\"$c\""
;;
*)
c="\"$c\""
;;
esac
if [ -n "$parse" ]; then
# Quote the rest once, so it gets processed by bash.
# Done this way so variables can get expanded.
while [ -n "$1" ]; do
c="$c \"$1\""
shift
done
else
# Otherwise, quote the arguments. The echo gets an extra
# space to prevent echo from parsing arguments like -n
while [ -n "$1" ]; do
t="${1//\'/\'\\\'\'}"
c="$c '$t'"
shift
done
fi
echo sudo "${opt[@]}" -- bash -xvc \""$c"\" >&2
command sudo "${opt[@]}" bash -xvc "$c"
else
echo sudo "${opt[@]}" >&2
command sudo "${opt[@]}"
fi
}
# Allow sudowrap to be used in subshells
export -f sudowrap
इस दृष्टिकोण का एक नुकसान यह है कि यह केवल उस फ़ंक्शन को विस्तारित करता है जिसे आप कॉल कर रहे हैं, न कि कोई अतिरिक्त फ़ंक्शन जिसे आप वहां से संदर्भित कर रहे हैं। काइल का दृष्टिकोण शायद इसे बेहतर ढंग से संभालता है यदि आप अपने bashrc में लोड किए गए कार्यों को संदर्भित कर रहे हैं (बशर्ते इसे bash -c
कॉल पर निष्पादित किया जाता है )।
आप export
अपने फ़ंक्शन को एक bash -c
उप-संस्करण या स्क्रिप्ट के लिए उपलब्ध करा सकते हैं जिसे आप इसका उपयोग करना चाहते हैं।
your_function () { echo 'Hello, World'; }
export -f your_function
bash -c 'your_function'
संपादित करें
यह प्रत्यक्ष उपधाराओं के लिए काम करता है, लेकिन जाहिरा तौर पर sudo
कार्यों (केवल चर) को अग्रेषित नहीं करता है। यहां तक कि विभिन्न संयोजनों का उपयोग करना setenv
, env_keep
और उपेक्षा env_reset
करना मदद के लिए प्रतीत नहीं होता है।
संपादित करें 2
हालांकि , ऐसा लगता है कि su
करता है समर्थन निर्यात कार्य करता है।
your_function () { echo 'Hello, World'; }
export -f your_function
su -c 'your_function'
bash: your_function: command not found
। मैं उपयोग कर रहा हूँ Ubuntu 11.04
और bash shell
।
sudo -E bash -c 'your_function'
?
शायद आप कर सकते हैं:
function meh() {
sudo -v
sudo cat /etc/shadow
}
यह काम करना चाहिए और कमांडलाइन पर आपको सुडो टाइप करने से बचाता है।
यदि आपको एक sudo के संदर्भ में एक फ़ंक्शन को कॉल करने की आवश्यकता है, तो आप उपयोग करना चाहते हैं declare
:
#!/bin/bash
function hello() {
echo "Hello, $USER"
}
sudo su another_user -c "$(declare -f hello); hello"
मैं एक नए शेल को निष्पादित करूँगा सूडो खुद शेल को निष्पादित करने के बाद, फिर फ़ंक्शन रूट विशेषाधिकारों के साथ चलेगा। उदाहरण के लिए कुछ इस तरह:
vim myFunction
#The following three lines go in myFunction file
function mywho {
sudo whoami
}
sudo bash -c '. /home/kbrandt/myFunction; mywho'
root
आप तब भी sudo bash
लाइन के लिए एक उपनाम बनाने के लिए जा सकते हैं ।
डेनिस विलियमसन के जवाब की टिप्पणियों में लेगोलस द्वारा बताया गया है कि आपको स्टैमोवरफ्लो पर पोस्ट किए गए इसी तरह के प्रश्न पर बारमगुलिज़ का उत्तर पढ़ना चाहिए ।
इससे शुरू करके मैंने इस मुद्दे को कवर करने के लिए एक फ़ंक्शन लिखा, जो मूल रूप से 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 के साथ कॉलिंग
नमस्ते रूट!
आपने निम्न पारम पारित किए हैं :
-एन
जॉन् किया
-s
फू
यदि आपको एक फ़ंक्शन को कॉल करने वाले शेल में इसका उपयोग करने की आवश्यकता है जो आपके bashrc में परिभाषित है, जैसा कि आपने पूछा था, तो आपको पिछले exesudo फ़ंक्शन को उसी bashrc फ़ाइल पर भी डालना होगा , जैसे कि निम्नलिखित:
function yourfunc ()
{
echo "Hello "$( whoami )"!"
}
export -f yourfunc
function exesudo ()
{
# copy here
}
export -f exesudo
फिर आपको लॉगआउट करना होगा और फिर से लॉगिन या उपयोग करना होगा
source ~/.bashrc
अंत में आप अनुसरण के रूप में एक्सडूडो का उपयोग कर सकते हैं:
$ yourfunc
Hello yourname!
$ exesudo yourfunc
Hello root!
/dev/shm/22481: No such file or directory
।