আমি কীভাবে sudo দিয়ে বাশ ফাংশন চালাতে পারি?


29

আমার কাছে একটি বৈশ্বিক বাশার্কে সংজ্ঞায়িত বাশ ফাংশন রয়েছে, যার কাজ করার জন্য মূল অধিকারগুলির প্রয়োজন। আমি কিভাবে এটা উবুন্টু সঙ্গে চালাতে পারেন, যেমন sudo myfunction। ডিফল্টরূপে এটি একটি ত্রুটি দেয়:

sudo: myfunction: কমান্ড পাওয়া যায় নি


2
কখনও চেষ্টা করা হয়নি, তবে এই ব্লগ পোস্টটি এটি হ্যান্ডেল করে বলে মনে হচ্ছে: w00tbl0g.blogspot.com/2007/05/…
গ্রিজলি

উপরের স্ক্রিপ্টটি ইনস্টল করার জন্য 'সেট ওরফে সুডো = সুদোআরাপ' দরকার যা imho বাঞ্ছনীয় নয়। সমাধানের জন্য দয়া করে আমার উত্তরটি দেখুন যাতে কোনও কাজ করার দরকার নেই।
লুকা বোররিওন

শেল ফাংশনগুলি খারাপ যে এটি অনেক কারণগুলির মধ্যে একটি। শেল ফাংশনগুলি আপনার পরিবেশ পরিবর্তন করতে চান এমন কমান্ডের মধ্যে সীমাবদ্ধ হওয়া উচিত। বাকীগুলির জন্য প্রকৃত স্ক্রিপ্টগুলি ব্যবহার করুন। একটি ফাংশন সুবিধা কি? (ঠিক আছে, "অতিব্যবহার" মন্দ, নিজেরাই কাজ করে না And এবং আমি বাজি ধরে থাকি যে আরও অনেক ভাল কারণ রয়েছে But তবে স্ক্রিপ্টগুলি লেখার সময় সেগুলি অবশ্যই নিয়ম নয়
not

উত্তর:


4

লুকা সদয়ভাবে আমাকে এই প্রশ্নের দিকে ইঙ্গিত করলেন, এখানে আমার পদ্ধতির: সুডোর কল করার আগে ফাংশন / ওরফে প্রসারিত করুন এবং এটি সম্পূর্ণরূপে সুডোর মধ্যে দিয়ে দিন, কোনও টেম্প ফাইলের প্রয়োজন নেই।

আমার ব্লগে এখানে ব্যাখ্যা করা হয়েছে । প্রচুর উদ্ধৃতি হ্যান্ডলিং রয়েছে :-)

# 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

এই পদ্ধতির একটি অসুবিধা হ'ল এটি কেবল আপনি যে ফাংশনটি কল করছেন তা প্রসারিত করে, সেখান থেকে আপনি যে কোনও অতিরিক্ত ফাংশন উল্লেখ করছেন তা নয়। আপনার বাশার্কে লোড হওয়া ফাংশনগুলি উল্লেখ করছেন (কালে এটি কার্যকর হয় bash -c) তবে কাইলের পদ্ধতিকে সম্ভবত এটি আরও ভালভাবে পরিচালনা করা হয় ।


সার্ভারফল্টে, আপনি পছন্দ করেছেন যে কোডটি পছন্দসই পাশাপাশি বাহ্যিক সাইটের সাথে সংযুক্ত করার পক্ষে এটি পছন্দ করা উচিত, যাতে ব্যবহারকারীরা তাদের পছন্দসই তথ্য পেতে দূরে ক্লিক করতে হয় না এবং তাই তথ্য বহিরাগত সাইটের সম্ভাব্য মৃত্যুর হাত থেকে বাঁচে।
সুসংগত কম্পাইলার

15

আপনি 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'

2
+1, আমি বলব এটি সঠিক উত্তর।
কাইল ব্র্যান্ড্ট

1
এই পদ্ধতিটি কাজ করে কিনা ?? আমার ক্ষেত্রে এটি হয় না।
প্রদীপচেত্রি

@ প্রদীপচেত্রি আপনি আরও তথ্য দিতে চাইবেন যেমন আপনি যা নিখুঁতভাবে চেষ্টা করছেন, কোন শেলটি আপনি ব্যবহার করেন এবং কোন ওএস ব্যবহার করেন।
লেগোলাস

@ লেগোলাস: উপরের স্ক্রিপ্টে আমি একই জিনিস লিখিত চেষ্টা করছি। আমি ত্রুটি পাচ্ছি bash: your_function: command not found। আমি ব্যবহার করছি Ubuntu 11.04এবং bash shell
প্রদীপচেত্রি

@ প্রদীপচেত্রে আপনি কী ব্যবহার করবেন sudo -E bash -c 'your_function'?
লেগোলাস

4

আপনি করতে পারেন:

function meh() {
    sudo -v
    sudo cat /etc/shadow
}

এটি কাজ করে এবং কমান্ডলাইনে sudo টাইপ করা থেকে বাঁচায়।


1
আপনার সিস্টেমে নির্ভর করে ... এটি আপনাকে sudo কমান্ডের প্রতিটি কল পাসওয়ার্ড প্রবেশ করানোর জন্য অনুরোধ জানাবে ... বা আপনাকে একবার অনুরোধ করবে এবং এটি ক্যাশে করবে। আপনি রুট হিসাবে চলছেন কিনা তা সনাক্ত করা ভাল এবং যদি না হয় ... তবে একবার সুদো দিয়ে আবার বাশ স্ক্রিপ্টটি কল করুন।
TheCompWiz

আমি এখনও এমন একটি সিস্টেমের মুখোমুখি হয়েছি যা সুডো পাসওয়ার্ড ক্যাশে করে না: টাইমস্ট্যাম্প_টাইমআউটআউটটির জন্য ডিফল্ট 5 হয় If আপনি যদি এটি 0 এ সেট করেন তবে আপনাকে সর্বদা একটি পাসওয়ার্ডের জন্য জিজ্ঞাসা করা হয়, তবে এটি একটি কাস্টম সেটিংস হবে।
wzzrd

3

আপনার যদি কোনও সুডোর প্রসঙ্গে কোনও ফাংশন কল করতে হয় তবে আপনি এটি ব্যবহার করতে চান declare:

#!/bin/bash

function hello() {
  echo "Hello, $USER"
}

sudo su another_user -c "$(declare -f hello); hello"

এটি কার্যকর হয়, যতক্ষণ না আপনার ফাংশনটি অন্য ফাংশনগুলিকে কল করে না।
modiX

আমার ব্যবহারের ক্ষেত্রে এটি সবচেয়ে ভাল উত্তর।
জিম

2

আমি শড নিজেই এক্সিকিউট করে একটি নতুন শেল এক্সিকিউট করব, তারপরে ফাংশনটি রুট সুবিধার সাথে চলবে with উদাহরণস্বরূপ যেমন:

vim myFunction
#The following three lines go in myFunction file
function mywho {
    sudo whoami
}

sudo bash -c '. /home/kbrandt/myFunction; mywho'
root

তারপরেও আপনি sudo bashলাইনের জন্য একটি উপকরণ তৈরি করতে যেতে পারেন ।


2
#!/bin/bash

function smth() {
    echo "{{"
    whoami
    echo "}}"
}

if [ $(whoami) != "root" ]; then
    whoami
    echo "i'm not root"
    sudo $0
else
    smth
fi

2

ডেনিস উইলিয়ামসনের উত্তরের মন্তব্যে লেগোলাসের দ্বারা নির্দেশিত হিসাবে আপনার স্ট্যাকওভারফ্লোতে পোস্ট করা অনুরূপ প্রশ্নের উপর বার্মুলিগুলির উত্তরটি পড়া উচিত ।

এ থেকে শুরু করে আমি এই ইস্যুটি কভার করার জন্য একটি ফাংশন লিখেছিলাম, যা মূলত 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



আউটপুট হবে

  1. সুডো ছাড়া কলিং
    হ্যালো আপনার নাম!
    আপনি নিম্নলিখিত প্যারামগুলি পাস করেছেন:
    প্রথম
    দ্বিতীয়

  2. সুডোর সাথে কলিং
    হ্যালো রুট!
    আপনি নিম্নলিখিত প্যারাম পাস:
    -n
    জন সম্পন্ন
    -s
    foo বিন্যাস



আপনার বাশার্কে সংজ্ঞায়িত কোন ফাংশনকে কল করে যদি আপনার শেলটিতে এটি ব্যবহার করার দরকার হয়, যেমনটি আপনি জিজ্ঞাসা করেছিলেন, তবে আপনাকে একই বাশার্ক ফাইলে আগের এক্সিজুডো ফাংশনটিও রাখতে হবে, নীচের মত:

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
modiX
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.