বাশ স্ক্রিপ্ট: সুডো সহ বা ছাড়াই কল করা হলে বিভিন্ন ফলাফল


10

উবুন্টু 16.04.3 এ, আমার খুব সাধারণ বাশ স্ক্রিপ্ট রয়েছে:

test.sh

[[ 0 == 0 ]] && result="true" || result="false"
echo $result
echo $USER $SHELL $0

আমি যখন এটি অ-রুট ব্যবহারকারী meহিসাবে বা হিসাবে ডাকি root, এটি প্রত্যাশার মতো কাজ করে। আমি যদি sudo ./test.shএটি ব্যবহার করি তবে এটি একটি সিনট্যাক্স ত্রুটির অভিযোগ করে:

$ ./test.sh
true
me /bin/bash ./test.sh

$ sudo su
# ./test.sh 
true
root /bin/bash ./test.sh

# exit
$ sudo ./test.sh
./test.sh: 1: ./test.sh: [[: not found
false
root /bin/bash ./test.sh

কি এই সৃষ্টি হতে পারে? আমি কীভাবে এটি ঠিক করতে পারি যাতে meএই স্ক্রিপ্টটি স্বাভাবিকভাবে এবং সাথে উভয়ই ব্যবহার করতে পারে sudo?


3
প্রো টিপ: দৌড়ানোর কোনও মানে নেইsudo su । শুধু চালানো sudo -iবা sudo -sপরিবর্তে।
টেরডন

@terdon স্থান sudo -iপরিবর্তন করে /rootsudo suবা sudo -sডিরেক্টরি অবস্থান পরিবর্তন করবেন না।
জেমস নিউটন

হ্যাঁ, কেন আমি আগে যুক্ত হওয়া প্রশ্নটি পড়ুন। এবং দুঃখিত, আমি আমার আগের মন্তব্যটি সম্পাদনা করেছি, আমি উল্লেখ করতে ভুলে গিয়েছিলাম -s
টেরডন

উত্তর:


20

প্রতিটি স্ক্রিপ্ট একটি দিয়ে শুরু হয় কুঁড়েঘর , শেল আপনার স্ক্রিপ্টটি শুরু জানে না যা ব্যাখ্যাকারী আপনার স্ক্রিপ্টটি চালানো উচিত তা ছাড়া 1 ক্ষেত্রে যেমন - এবং যথাসাধ্য sudo ./script.shএখানে - সঙ্গে এটি চালানোর sh, যা উবুন্টু 16,04 মধ্যে লিঙ্ক করা হয়েছে dashশর্তাধীন অভিব্যক্তি [[ একটি হল bashযৌগ কমান্ড , তাই dashকিভাবে এটি হ্যান্ডেল এবং ত্রুটি আপনি সম্মুখীন ছোঁড়ার করতে জানে না।

সমাধান এখানে যুক্ত করা হয়

#!/bin/bash

আপনার স্ক্রিপ্ট প্রথম লাইন হিসাবে। আপনি এটির সাথে স্পষ্টভাবে কল করলে আপনি একই ফলাফল পেতে পারেন sudo bash ./script.shতবে একটি শেবাং যাওয়ার উপায় go
কোন শেল আপনার স্ক্রিপ্টটি চালায় তা পরীক্ষা echo $0করতে এটিতে যুক্ত করুন। এটা হিসাবে একই নয় echo $SHELL , উদ্ধৃত wiki.archlinux.org :

শেলটিতে ব্যবহারকারীর পছন্দের শেলটির পথ রয়েছে। মনে রাখবেন যে এটি বর্তমানে চলমান শেল নয়, যদিও বাশ শুরুতে এই পরিবর্তনশীলটি সেট করে।

1: আপনি শুরু হিসাবে ./test.shসঙ্গে bashএটা ঠিক অধিকৃত bash, একই জন্য যায় sudo susubshell।


1
এছাড়াও নোট করুন যে বাশ ব্যাশ ব্যবহার করে শেবাং ছাড়াই স্ক্রিপ্ট চালায় /bin/sh
muru

@ ডিজিটার এটি ঠিক করে দেয়। ধন্যবাদ! কোন শেলটি এটি চালাচ্ছে আমি কোনও স্ক্রিপ্টের মধ্যে থেকে কীভাবে তা পরীক্ষা করতে পারি ? ( echo $0আমাকে স্ক্রিপ্টটির নাম দেয় ./test.sh:)
জেমস নিউটন

@ জেমস নিউটনের কাছে পোর্টেবল উপায় নেই, এএফআইএইচ, তবে আপনি কোনটি /proc/$$/exeনির্দেশ করতে পারেন তা পরীক্ষা করতে পারেন । এছাড়াও আপনি মত বিভিন্ন ভেরিয়েবল পরীক্ষা করতে পারেন $BASH_VERSION, $ZSH_VERSIONইত্যাদি (কিন্তু ড্যাশ এমন কোন পরিবর্তনশীল সেট না)
muru

5

@ ডিজিটর ব্যাখ্যা হিসাবে , এখানে সমস্যাটি হ'ল আপনার স্ক্রিপ্টে শেবাং লাইন নেই । একটি শেবাং ছাড়াই, sudoফাইলটি ব্যবহার করে চালানোর চেষ্টা করতে ডিফল্ট হবে /bin/sh। আমি এটি কোথাও নথিভুক্ত দেখতে পেলাম না, তবে আমি sudoযেখানে ফাইলটিতে নিম্নলিখিতটি পেয়েছি তার উত্স কোড পরীক্ষা করে নিশ্চিত করেছিলাম pathnames.h:

#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */

এর অর্থ "ভেরিয়েবল _PATH_BSHELLসংজ্ঞায়িত না হলে সেট করুন /bin/sh" এটিকে সেট করুন "। তারপরে, configureসোর্স টার্বল অন্তর্ভুক্ত স্ক্রিপ্টটিতে আমাদের রয়েছে:

for p in "/bin/bash" "/usr/bin/sh" "/sbin/sh" "/usr/sbin/sh" "/bin/ksh" "/usr/bin/ksh" "/bin/bash" "/usr/bin/bash"; do
    if test -f "$p"; then
    found=yes
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $p" >&5
$as_echo "$p" >&6; }
    cat >>confdefs.h <<EOF
#define _PATH_BSHELL "$p"
EOF

    break
    fi
done

এই লুপ জন্য চেহারা হবে /bin/bash, /usr/bin/sh, /sbin/sh, /usr/sbin/shবা /bin/kshএবং তারপর সেট করে _PATH_BSHELLকরতে যেটি আগে পাওয়া যায়নি । যেহেতু /bin/shতালিকার প্রথমটি ছিল এবং এটি বিদ্যমান, _PATH_BSHELLসেট করা আছে /bin/sh। এই সমস্তটির ফলাফল হ'ল ডিফল্ট শেল sudoঅন্যথায় সংজ্ঞায়িত না করা হয় /bin/sh

সুতরাং, উবুন্টু sudoব্যবহার করে চলমান জিনিসগুলিতে ডিফল্ট হবে /bin/shএবং এটি dashএকটি ন্যূনতম পসিক্স অনুগত শেল:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27  2015 /bin/sh -> dash

[[কনস্ট্রাক্ট একটি ব্যাশ বৈশিষ্ট্য, এটা POSIX মান দ্বারা সংজ্ঞায়িত করা হয় না হয় এবং বোঝা হয় না dash:

$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found

বিস্তারিতভাবে, আপনি যে তিনটি অনুরোধে চেষ্টা করেছেন:

  1. ./test.sh

    না sudo; শেবাং লাইনের অভাবে, আপনার শেলটি ফাইলটি নিজেই চালিত করার চেষ্টা করবে। যেহেতু আপনি চালাচ্ছেন bash, এটি কার্যকরভাবে bash ./test.shকাজ করবে এবং কাজ করবে।

  2. sudo suদ্বারা অনুসরণ ./test.sh

    এখানে, আপনি ব্যবহারকারীর জন্য একটি নতুন শেল শুরু করছেন root। এটি $SHELLসেই ব্যবহারকারীর জন্য পরিবেশ পরিবর্তনশীলে শেল যে কোনও সংজ্ঞায়িত হবে এবং উবুন্টুতে মূলের ডিফল্ট শেলটি হ'ল bash:

    $ grep root /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    
  3. sudo ./test.sh

    এখানে আপনি sudoসরাসরি কমান্ডটি কার্যকর করতে দিচ্ছেন। যেহেতু এর ডিফল্ট শেলটি /bin/shউপরে বর্ণিত হিসাবে তৈরি করা হয়েছে, এটি স্ক্রিপ্টটি এটি দিয়ে চালিত করে /bin/shযা এটি dashএবং এটি ব্যর্থ হওয়ায় এটি dashবুঝতে ব্যর্থ হয় [[


দ্রষ্টব্য : sudoডিফল্ট শেলটি কীভাবে সেট করে তার বিশদটি কিছুটা জটিল বলে মনে হচ্ছে। আমি আমার উত্তরে উল্লিখিত ফাইলগুলিকে নির্দেশ করতে চেষ্টা করেছি /bin/bashকিন্তু sudoএখনও ডিফল্ট ছিলাম /bin/sh। সুতরাং উত্স কোডে অন্য কয়েকটি জায়গা থাকতে হবে যেখানে ডিফল্ট শেলটি সংজ্ঞায়িত। তবুও, মূল পয়েন্টটি (যা sudoডিফল্ট হয়েছে sh) এখনও দাঁড়িয়ে আছে।


আমি এটি কোথাও নথিভুক্ত খুঁজে পাইনি - আমিও না, আমি কেবল ধরে /bin/shনিয়েছি এটি ত্রুটি বার্তা থেকে ব্যবহার করবে - এটি আর কী হতে পারে? সুডো কী শেল ব্যবহার করে in সুতরাং man sudo, বিভাগ কম্যান্ড এক্সিকিউশন , এ আরও দেখুন in এমন প্রশ্নের মধ্যে প্রশ্নের সুন্দর উত্তর দেওয়া হয়েছে । দেখা যাচ্ছে sudoকোনও মধ্যবর্তী শেল ব্যবহার করে না !
মিষ্টান্ন

1
@ ডেজারেট হ্যাঁ, এটি execveসিস্টেম কলটির নিজস্ব বাস্তবায়ন ব্যবহার করে যা ডিফল্ট sh। এবং না, মধ্যবর্তী শেলগুলি অপ্রাসঙ্গিক, এটি কমান্ডটি চালিত শেল সম্পর্কে নয় তবে প্রদত্ত শেল স্ক্রিপ্টটি পড়তে ব্যবহৃত শেল ইন্টারপ্রেটার সম্পর্কে। সুতরাং না, এটি একটি মধ্যবর্তী শেলটি চালু করে না তবে এটি এখনও শেল স্ক্রিপ্টগুলির জন্য একটি শেল ইন্টারপ্রেটারের প্রয়োজন।
টেরডন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.