Sudo বা su এর মাধ্যমে কোনও স্ক্রিপ্ট চালানোর সময় আমি আসল ব্যবহারকারীটি পেতে চাই। এই একাধিক নির্বিশেষে ঘটা উচিত sudoবা suরান একে অপরের এবং বিশেষভাবে ভিতরে sudo su -।
উত্তর:
ফলাফল:
অন্য কোনও পদ্ধতির গ্যারান্টিযুক্ত হিসাবে who am i | awk '{print $1}'OR ব্যবহার করুন logname।
স্ব হিসাবে লগ ইন:
evan> echo $USER
evan
evan> echo $SUDO_USER
evan> echo $LOGNAME
evan
evan> whoami
evan
evan> who am i | awk '{print $1}'
evan
evan> logname
evan
evan>
সাধারণ সুডো:
evan> sudo -s
root> echo $USER
root
root> echo $SUDO_USER
evan
root> echo $LOGNAME
root
root> whoami
root
root> who am i | awk '{print $1}'
evan
root> logname
evan
root>
sudo su -:
evan> sudo su -
[root ]# echo $USER
root
[root ]# echo $SUDO_USER
[root ]# echo $LOGNAME
root
[root ]# whoami
root
[root ]# who am i | awk '{print $1}'
evan
[root ]# logname
evan
[root ]#
sudo su -; সু টম:
evan> sudo su -
[root ]# su tom
tom$ echo $USER
tom
tom$ echo $SUDO_USER
tom$ echo $LOGNAME
tom
tom$ whoami
tom
tom$ who am i | awk '{print $1}'
evan
tom$ logname
evan
tom$
who am iএকই who smells bad। এছাড়াও, এটি কেবল তখনই কাজ করে যদি STDINকোনও টিটিওয়াইয়ের সাথে যুক্ত থাকে । সুতরাং আপনি echo "hello" | who am iএটি চালানো সহজভাবে কাজ করবে না।
echo "hello" | who am iআপনার স্ক্রিপ্টটি এমন পরিবেশে চলমান নেই যেখানে টার্মিনাল নেই You তারপরে আপনি দেখতে পাচ্ছেন যে ত্রুটিটি who am iকাজ করছে না কারণ অ-পঠনযোগ্য স্টিডিনের সাথে একরকম সমস্যা রয়েছে, সেই ক্ষেত্রে who am iস্ট্যান্ডিনের প্রয়োজনীয়তা মেটানোর জন্য আপনি হতাশার জন্য ডেটাতে পাইপিংয়ের চেষ্টা করতে পারেন । টাইলার সবেমাত্র লক্ষ করছে যে সে ইতিমধ্যে সেই পথে নেমেছে, এবং পাইপটি কাজ করবে না কারণ স্টিডিন অবশ্যই পাঠ্য এবং একটি টিটিওয়াইয়ের সাথে যুক্ত থাকতে হবে।
lognameএখন ব্যবহার করছি , যা দেখা যাচ্ছে যে কাজ করে, কোথায় who am iহয় না।
কোন সঠিক উত্তর নেই। আপনি যখন ব্যবহারকারী আইডি পরিবর্তন করেন, মূল ব্যবহারকারী আইডি সাধারণত সংরক্ষণ করা হয় না, তাই তথ্যটি হারিয়ে যায়। কিছু প্রোগ্রাম, যেমন lognameএবং who -mএকটি হ্যাক বাস্তবায়ন করে যেখানে তারা কোন টার্মিনালে সংযুক্ত আছে stdinতা পরীক্ষা করে দেখুন এবং তারপরে সেই টার্মিনালে ব্যবহারকারী কোন লগ ইন করেছেন তা পরীক্ষা করে দেখুন।
এই সমাধানটি প্রায়শই কাজ করে, তবে নির্বোধ নয় এবং অবশ্যই এটি নিরাপদ হিসাবে বিবেচনা করা উচিত নয়। উদাহরণস্বরূপ, কল্পনা করুন whoযে নিম্নলিখিতগুলি আউটপুট দেয়:
tom pts/0 2011-07-03 19:18 (1.2.3.4)
joe pts/1 2011-07-03 19:10 (5.6.7.8)
tomsuরুট পেতে ব্যবহৃত , এবং আপনার প্রোগ্রাম চালায়। যদি STDINপুনঃনির্দেশিত না হয়, তবে উইলের মতো একটি প্রোগ্রাম lognameআউটপুট দেয় tom। যদি এটি পুনঃনির্দেশিত হয় (যেমন কোনও ফাইল থেকে):
logname < /some/file
তারপরে ফলাফলটি " no login name" হয়, যেহেতু ইনপুটটি টার্মিনাল নয়। আরও আকর্ষণীয়ভাবে এখনও, যদিও, ব্যবহারকারীটি অন্য কোনও লগ-ইন ব্যবহারকারী হিসাবে পোজ দিতে পারে। জো যেহেতু pts / 1 এ লগইন হয়েছে, টম দৌড়ে তাঁর হয়ে ভান করতে পারে
logname < /dev/pts1
এখন, এটি বলছে joeযদিও টম হ'ল কমান্ডটি চালানো। অন্য কথায়, আপনি যদি এই প্রক্রিয়াটি কোনও ধরণের সুরক্ষার ভূমিকাতে ব্যবহার করেন তবে আপনি ক্রেজি।
এটি kshএইচপি-ইউএক্স-এ লিখেছি এমন একটি ফাংশন। Bashলিনাক্সে এটি কীভাবে কাজ করবে তা আমি জানি না । ধারণাটি হ'ল sudoপ্রক্রিয়াটি মূল ব্যবহারকারী হিসাবে চলছে এবং শিশু প্রক্রিয়াগুলি লক্ষ্য ব্যবহারকারী। প্যারেন্ট প্রসেসগুলির মাধ্যমে সাইকেল চালিয়ে আমরা মূল প্রক্রিয়াটির ব্যবহারকারীর সন্ধান করতে পারি।
#
# The options of ps require UNIX_STD=2003. I am setting it
# in a subshell to avoid having it pollute the parent's namespace.
#
function findUser
{
thisPID=$$
origUser=$(whoami)
thisUser=$origUser
while [ "$thisUser" = "$origUser" ]
do
( export UNIX_STD=2003; ps -p$thisPID -ouser,ppid,pid,comm ) | grep $thisPID | read thisUser myPPid myPid myComm
thisPID=$myPPid
done
if [ "$thisUser" = "root" ]
then
thisUser=$origUser
fi
if [ "$#" -gt "0" ]
then
echo $origUser--$thisUser--$myComm
else
echo $thisUser
fi
return 0
}
আমি জানি যে আসল প্রশ্নটি অনেক আগে থেকেই হয়েছিল তবে লোকেরা (যেমন আমার মতো) এখনও জিজ্ঞাসা করছে এবং সমাধানটি দেওয়ার জন্য এটি একটি ভাল জায়গা বলে মনে হয়েছিল।
ব্যবহারকারীর লগইন নাম পেতে লগনাম (1) ব্যবহার সম্পর্কে কীভাবে?
logname(1)কাজ করে না কিন্তু lognameনা - উপরে ফলাফল যোগ
$LOGNAMEকরেছিলাম কিন্তু কাজ হয়নি। উপরের ফলাফলগুলিতেও যুক্ত হয়েছে।
lognameএখনও একটি TTY প্রয়োজন? আমার পরীক্ষার সাথে এটি সর্বদা পাস করে। (সম্ভবত আমি কিছু ভুল করছি।) আমি কোর্টিলস 8.26 দিয়ে লিনাক্স চালাচ্ছি।
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
এটাই আমার পক্ষে কাজ করেছে।
user1683793 এর FindUser () ফাংশনটি পোর্ট করা হয়েছে bashএবং প্রসারিত হয়েছে যাতে এটি এনএসএস লাইব্রেরিতে সংরক্ষিত ব্যবহারকারীর নামও দেয় ।
#!/bin/bash
function findUser() {
thisPID=$$
origUser=$(whoami)
thisUser=$origUser
while [ "$thisUser" = "$origUser" ]
do
ARR=($(ps h -p$thisPID -ouser,ppid;))
thisUser="${ARR[0]}"
myPPid="${ARR[1]}"
thisPID=$myPPid
done
getent passwd "$thisUser" | cut -d: -f1
}
user=$(findUser)
echo "logged in: $user"
সাইক্লিং ফিরে এবং ব্যবহারকারীদের একটি তালিকা প্রদান
user1683793 এর উত্তরের ভিত্তিতে
নন-টিটিওয়াই প্রসেসগুলি এক্সক্লুড করে আমি লগইনের সূচনাকারী হিসাবে রুট এড়িয়ে চলেছি। আমি নিশ্চিত নই যে এটি কোনও ক্ষেত্রে খুব বেশি ক্ষতিগ্রস্থ হতে পারে কিনা
#!/bin/ksh
function findUserList
{
typeset userList prevUser thisPID thisUser myPPid myPid myTTY myComm
thisPID=$$ # starting with this process-ID
while [ "$thisPID" != 1 ] # and cycling back to the origin
do
( ps -p$thisPID -ouser,ppid,pid,tty,comm ) | grep $thisPID | read thisUser myPPid myPid myTTY myComm
thisPID=$myPPid
[[ $myComm =~ ^su ]] && continue # su is always run by root -> skip it
[[ $myTTY == '?' ]] && continue # skip what is running somewhere in the background (without a terminal)
if [[ $prevUser != $thisUser ]]; then # we only want the change of user
prevUser="$thisUser" # keep the user for comparing
userList="${userList:+$userList }$thisUser" # and add the new user to the list
fi
#print "$thisPID=$thisUser: $userList -> $thisUser -> $myComm " >&2
done
print "$userList"
return 0
}
lognameবা who am iআমাকে, আকাঙ্ক্ষিত উত্তর দেন নি, বিশেষ করে আর তালিকায় না su user1, su user2, su user3,...
আমি জানি যে আসল প্রশ্নটি অনেক আগে থেকেই হয়েছিল তবে লোকেরা (যেমন আমার মতো) এখনও জিজ্ঞাসা করছে এবং সমাধানটি দেওয়ার জন্য এটি একটি ভাল জায়গা বলে মনে হয়েছিল।
পিএস একাধিকবার কল করার বিকল্প: একটি pstree কল করুন
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
আউটপুট (যখন সমান হিসাবে লগ ইন করা হয়): (evan)
pstree যুক্তি:
প্রথম ব্যবহারকারী পরিবর্তন (যা লগইন হল) পান grep -oএবং head।
সীমাবদ্ধতা: কমান্ডটিতে কোনও ধনুর্বন্ধনী থাকতে পারে না ()(এটি সাধারণত হয় না)
চলমান সিস্টেমে systemd-logind, সিস্টেমড এপিআই এই তথ্য সরবরাহ করে । আপনি যদি শেল স্ক্রিপ্ট থেকে এই তথ্যটি অ্যাক্সেস করতে চান তবে এই জাতীয় কিছু ব্যবহার করা দরকার:
$ loginctl session-status \
| (read session_id ignored; loginctl show-session -p User $session_id)
User=1000
session-statusএবং show-ssessionসিস্টেম কমান্ড loginctlআর্গুমেন্ট ছাড়া বিভিন্ন আচরণ আছে: session-statusবর্তমান সেশন ব্যবহার করে, কিন্তু show-ssessionম্যানেজার ব্যবহার করে। তবে, show-sessionমেশিন-পঠনযোগ্য আউটপুটের কারণে স্ক্রিপ্ট ব্যবহারের জন্য ব্যবহার করা পছন্দনীয়। এজন্য দু'জনের আমন্ত্রণ loginctlপ্রয়োজন।
who | awk '{print $1}'