উত্তর:
sudo su -এটি লেখার জটিল পদ্ধতি যা sudo -iএকটি প্রাচীন পরিবেশ তৈরি করে। এটি লগইন শেলের মূল বিষয়। এমনকি একটি সমতল sudoপরিবেশ থেকে বেশিরভাগ ভেরিয়েবল সরিয়ে দেয়। তদতিরিক্ত sudoএকটি বাহ্যিক আদেশ; নিজেই শেল স্ক্রিপ্টে সুবিধাগুলি বাড়ানোর কোনও উপায় নেই, কেবল sudoঅতিরিক্ত সুবিধাসহ একটি বহিরাগত প্রোগ্রাম ( ) চালানোর জন্য , এবং এর অর্থ কোনও শেল ভেরিয়েবল (যেমন অ-রফতানি ভেরিয়েবল) এবং প্যারেন্ট শেলের মধ্যে সংজ্ঞায়িত ফাংশনগুলি উপলব্ধ হবে না শিশু শেল
আপনি লগইন শেলটি ( বা sudo bashপরিবর্তে ) না চাওয়া এবং এই ভেরিয়েবলগুলি ( ফাইলের সাথে বা এর মধ্যে ) যেতে দিতে sudo কনফিগার না করে আপনি পরিবেশের ভেরিয়েবলগুলি পাস করতে পারেন । এটি আপনাকে ফাংশনগুলির জন্য সহায়তা করবে না (যদিও ব্যাশের একটি ফাংশন রফতানির সুবিধা রয়েছে, এটি সুডো ব্লক করে)।sudo su -sudo -iDefaults !env_resetDefaults env_keep=…sudoers
চাইল্ড শেলের আপনার ক্রিয়াকলাপগুলি পাওয়ার সাধারণ উপায় হ'ল সেগুলি এখানে সংজ্ঞায়িত করা। উদ্ধৃতি দেওয়ার ক্ষেত্রে খেয়াল রাখুন: আপনি যদি <<EOFএখানে নথির জন্য ব্যবহার করেন তবে এখানের নথির বিষয়বস্তু প্রথমে প্যারেন্ট শেল দ্বারা প্রসারিত হবে এবং সেই প্রসারণের ফলাফলটি শিশু শেলটি দেখতে পাওয়া স্ক্রিপ্টে পরিণত হয়। অর্থাৎ আপনি যদি লিখেন
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
এটি লক্ষ্য ব্যবহারকারীর নয়, মূল ব্যবহারকারীর নাম প্রদর্শন করে। এই প্রথম পর্বের প্রসারণ এড়াতে <<অপারেটরের পরে এখানে নথির চিহ্নিতকারীকে উদ্ধৃত করুন :
sudo -u "$target_user" -i <<'EOF'
echo "$(whoami)"
EOF
সুতরাং আপনার যদি পিতামাত্ত শেল থেকে চাইল্ড শেলের কাছে ডেটা দেওয়ার দরকার না হয় তবে আপনি এখানে উদ্ধৃত ডকুমেন্টটি ব্যবহার করতে পারেন:
#!/bin/bash
sudo -u "$target_user" -i <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}"
EOF
আপনি যখন পিতামাত্ত শেল থেকে চাইল্ড শেলের কাছে ডেটা প্রেরণ করতে এখানে একটি অনাদায়ী এখানে ডকুমেন্ট মার্কার ব্যবহার করতে পারেন, ডেটাতে কোনও বিশেষ অক্ষর না থাকলে এটি কেবল কাজ করে। এটি কারণ যেমন একটি স্ক্রিপ্ট
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
এর আউটপুট whoamiএকটি স্ট্রিং নয়, কিছুটা শেল কোড হয়ে যায়। উদাহরণস্বরূপ, যদি whoamiকমান্ডটি ফিরে আসে "; rm -rf /; "trueতবে চাইল্ড শেল কমান্ডটি কার্যকর করবে echo ""; rm -rf /; "true"।
যদি আপনাকে প্যারেন্ট শেল থেকে ডেটা পাস করতে হয় তবে একটি সহজ উপায় হ'ল এটি আর্গুমেন্ট হিসাবে পাস করা। শিশু শেলটি স্পষ্টভাবে চাওয়া এবং এটি অবস্থানগত পরামিতিগুলি পাস করুন:
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i sh _ "$extVAR" <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
পাস করার জন্য আপনার যদি একাধিক ভেরিয়েবল থাকে তবে নাম দিয়ে সেগুলি পাঠানো আরও পঠনযোগ্য। envশিশু শেলের জন্য পরিবেশের ভেরিয়েবলগুলি সেট করতে স্পষ্টভাবে কল করুন ।
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i env extVAR="$extVAR" sh <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
মনে রাখবেন যে আপনি যদি প্রত্যাশিত হন /etc/profileএবং লক্ষ্য ব্যবহারকারীর ~/.profileপড়তে হয় তবে আপনাকে সেগুলি স্পষ্টভাবে পড়তে হবে, বা bash --loginপরিবর্তে কল করতে হবে sh।
এটি কাজ করে না কারণ log_fআপনি যে sudo su -শেলটি চালু করছেন তাতে ফাংশনটি ঘোষিত হয়নি । পরিবর্তে:
extVAR="yourName"
sudo su - <user> << EOF
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f ${intVAR} ${extVAR}
EOF
রুট সাবশেলে আপনাকে ফাংশনটি সংজ্ঞায়িত করতে হবে। এটি এটি করতে পারে, তবে .... আমি জানি না যে বেশিরভাগ স্টাফ কী করে। অন্তত - তাই যতদিন তন্ন তন্ন sudoনা suচাহিদা একটি পাসওয়ার্ড পড়তে stdin - উচিত যে log_f()ঘোষণা করেন।
আমি বিশ্বাস করি যে আপনি সেই মানগুলি মূল শেলটির ইনপুটগুলিতে প্রসারিত করতে চান। যদি আপনি এটি করতে না চান তবে আপনার উদ্ধৃত করা উচিত EOFএবং ভারগুলি নিজেরাই।
আমার ক্ষেত্রে আমাকে একটি অ্যারে পাস করার দরকার ছিল এবং কিছুটা সমস্যা হয়েছিল তবে কিছুক্ষণ পরে সাফল্য পেয়েছিলাম অ্যারের মানগুলি এক- envকিকে প্রতিপন্ন করে এবং উদ্দেশ্য কোডটি মোড়ক করে bash -c '<intended code>'এবং মূলত এটি অ্যারে পুনরায় পুনঃস্থাপন করে যেমন: INNER_KEY=($<env_key>).:
পরীক্ষার জন্য:
#!/usr/bin/env bash
PLUGINS=(foo bar baz)
sudo -u <some-user> -i env PLUGINS="`echo ${PLUGINS[@]}`" sh <<'EOF'
bash -c '
FOO=($PLUGINS);
echo values: \[${FOO[@]}\];
for pl in ${FOO[@]};
do echo value: $pl;
done;
'
EOF
সমস্যাটি হ'ল আমি নীচের মতো সরাসরি কিছু করতে পারি না (ব্যবহার না করে bash -c '...'):
FOO=($PLUGINS);
for pl in ${FOO[@]};
...