मैं सभी उपयोगकर्ता नाम और / या होम निर्देशिका कैसे सूचीबद्ध कर सकता हूं?


16

मैं मशीन पर सभी उपयोगकर्ताओं को सूचीबद्ध करना चाहता हूं। आमतौर पर, मैं करूंगा:

ls -l /home

लेकिन मैं इसे एक स्क्रिप्ट में उपयोग करता हूं जिसे अन्य मशीनों पर तैनात किया जाएगा और शायद उन मशीनों पर वे इसे घर नहीं कहते हैं (जैसे myHome)। इसलिए मैं इसे सामान्य बनाना चाहता हूं ls -l ~। लेकिन यह सिर्फ सभी उपयोगकर्ताओं के होम डायर के नाम के बजाय मेरे उपयोगकर्ताओं के होम डायर को सूचीबद्ध करता है (मूल रूप से मैं मशीन पर उपयोगकर्ताओं के नामों की एक सूची प्राप्त करना चाहता हूं)। मैं इसे कैसे सामान्य कर सकता हूं?


19
वास्तव में, इस बात की कोई गारंटी नहीं है कि सभी उपयोगकर्ताओं के घर निर्देशिका किसी एक निर्देशिका के उपनिर्देशिका हैं ।
होब्स

17
@hobbs या उपयोगकर्ता के लॉग इन करने तक भी वे मौजूद रहते हैं। यह उन स्पष्ट रूप से सरल मुद्दों में से एक है जो वास्तव में जल्दी से जटिल हो जाता है।
एइटबिटोनी

11
ध्यान रखें कि ~आम तौर पर है के बराबर /home/user, नहीं की /homeया /home/*(जो अपने इरादे के करीब होने लगते हैं)।
एथन कामिन्स्की

2
@EightBitTony: ... और न ही इस बात की कोई गारंटी है कि होम डायरेक्टरी बिल्कुल मौजूद है । उदाहरण के लिए, मेरे उबंटू इंस्टॉल पर, कई सिस्टम उपयोगकर्ताओं (सहित nobody) के पास अपने घर की निर्देशिका है /nonexistent, जो स्पष्ट रूप से मौजूद नहीं है। (बेशक, उन उपयोगकर्ताओं के पास भी अपना पासवर्ड हैश सेट है *और उनका शेल सेट है /usr/sbin/nologinया /bin/false, इसलिए वे वास्तव में शुरू करने के लिए सामान्य अर्थ में लॉग इन नहीं कर सकते हैं।)
इल्मरी करोनें

1
दूसरी ओर, (पुराना स्कूल) एनएफएस सर्वर उन उपयोगकर्ताओं के लिए घर निर्देशिकाओं की सेवा कर सकता है जिन्हें इसके ओएस के नाम से नहीं जाना जाता है।
रैकडॉन्बिनमैन

जवाबों:


45

कई प्रणालियों एक है getentसूची में आदेश या की सामग्री क्वेरी नाम सेवा जैसे डेटाबेस passwd, group, services, protocols...

getent passwd | cut -d: -f6

घर निर्देशिका (6 सूची चाहेंगे वें डेटाबेस किया जा सकता है में सभी उपयोगकर्ताओं के पेट के सीमांकित क्षेत्र) प्रगणित

उपयोगकर्ता नाम स्वयं पहले फ़ील्ड में है, इसलिए उपयोगकर्ता नामों की सूची के लिए:

getent passwd | cut -d: -f1

(ध्यान दें कि इसका मतलब यह नहीं है कि उपयोगकर्ता सिस्टम में लॉग इन कर सकते हैं या उनकी होम डायरेक्टरी बनाई गई है, लेकिन यह कि वे सिस्टम के लिए जाने जाते हैं, उन्हें एक यूजर आईडी में अनुवाद किया जा सकता है)।

उन डेटाबेस के लिए जिन्हें एनुमरेट नहीं किया जा सकता है, आप व्यक्तिगत रूप से प्रत्येक संभावित यूजर आईडी की कोशिश और क्वेरी कर सकते हैं:

getent passwd {0..65535} | cut -d: -f1,6

(यहां मान लिया गया कि 65535 पर यूडीएस रुक जाता है (कुछ सिस्टम अधिक समर्थन करते हैं) और एक शेल जो {x..y}ब्रेस के विस्तार का समर्थन करता है )। लेकिन आप ऐसा नहीं करना चाहेंगे कि अक्सर उन प्रणालियों पर जहां उपयोगकर्ता डेटाबेस नेटवर्क है (और वहां सीमित स्थानीय कैशिंग है) जैसे LDAP, NIS +, SQL ... क्योंकि इससे बहुत अधिक नेटवर्क ट्रैफ़िक हो सकता है (और निर्देशिका सर्वर पर लोड हो सकता है) ) उन सभी प्रश्नों को बनाने के लिए।

इसका मतलब यह भी है कि यदि एक ही यूआईडी को साझा करने वाले कई उपयोगकर्ता हैं, तो आपको प्रत्येक यूआईडी के लिए केवल एक प्रविष्टि मिलेगी, इसलिए दूसरों को याद करें।

यदि आपके पास नहीं है getent, तो आप इसका सहारा ले सकते हैं perl:

perl -le 'while (@e = getpwent) {print $e[7]}'

के लिए getent passwd( $e[0]उपयोगकर्ता नाम के लिए), या:

perl -le 'for ($i=0;$i<65536;++$i) {
  if (@e = getpwuid $i) {print $e[0] ": " $e[7]}}'

getent passwd {0..65535}एक ही caveats के साथ के लिए ।

गोले में, आप ~userघर की निर्देशिका प्राप्त करने के लिए उपयोग कर सकते हैं user, लेकिन अधिकांश गोले में, यह केवल उपयोगकर्ता नामों के सीमित सेट के लिए काम करता है (उस ~विस्तार ऑपरेटर के लिए समर्थित उपयोगकर्ता नामों में अनुमत वर्णों की सूची शेल से शेल तक भिन्न होती है) और के साथ कई गोले (सहित bash), ~$userकाम नहीं करेंगे (आपको evalउपयोगकर्ता के नाम को वहां चर में संग्रहीत करने पर सहारा लेना होगा)। और आपको उपयोगकर्ता नामों की सूची प्राप्त करने के लिए अभी भी एक रास्ता खोजना होगा।

कुछ शेल में उपयोगकर्ता नाम की सूची प्राप्त करने के लिए बिलिन समर्थन होता है।

  • bash: compgen -uउन डेटाबेस में उपयोगकर्ताओं की सूची लौटाएगा जिन्हें गणना की जा सकती है।
  • zsh: $userdirsसाहचर्य सरणी उपयोगकर्ता के नामों को उनके होम डायरेक्टरी में (उन डेटाबेस तक सीमित है, जिन्हें एनुमरेट किया जा सकता है, लेकिन यदि आप किसी ~userऐसे उपयोगकर्ता के लिए विस्तार करते हैं, जो गैर- एन्यूमरेबल डेटाबेस में है, तो एक प्रविष्टि जोड़ी जाएगी $userdirs)। तो आप कर सकते हैं:

    printf '%s => %s\n' "${(kv@)userdirs}"

    उपयोगकर्ताओं को उनके घर निर्देशिका के साथ सूचीबद्ध करने के लिए।

    यह तभी काम करता है जब zshइंटरेक्टिव हो

  • tcsh, fishऔर yashतीन अन्य गोले हैं जो उपयोगकर्ता के नामों को पूरा कर सकते हैं (उदाहरण के लिए ~<Tab>तर्क पूरा करते समय), लेकिन ऐसा नहीं लगता कि वे आपको उपयोगकर्ता नामों की सूची को प्रोग्रामिक रूप से प्राप्त करने देते हैं।


ओपी के लिए चुनौती यह जानना होगा कि क्या getentहोने वाला है, जो मुझे लगता है कि कुछ हद तक उनकी 'अन्य मशीनों' के दायरे पर निर्भर करता है।
एइटबिटोनी

1
@EightBitTony, मैंने एक perlविकल्प जोड़ा है ।
स्टीफन चेज़लस

1
मैक पर, यह शायद ओपन डायरेक्टरी को शामिल करने वाला कुछ है।
सिल्वरवॉल्फ - मोनिका

@seaturtle, macOS perl -le 'while (@e = getpwent) {print $e[7]}'पर ठीक काम करता है।
स्टीफन चेज़ेलस

1
@FloHe, वे उपयोगकर्ता नाम हैं। यूनिक्स सिस्टम पर अधिकांश उपयोगकर्ता विशेष सिस्टम उपयोगकर्ता हैं, जिनका जीवन रनिंग सिस्टम सेवाओं के लिए समर्पित है। getent passwdआपको उपयोगकर्ता डेटाबेस दिखाता है। पहला फ़ील्ड उपयोगकर्ता नाम है, 6 वीं फ़ील्ड उपयोगकर्ता होम निर्देशिका है।
स्टीफन चेजेलस 15

17

उपयोगकर्ता के घर निर्देशिकाओं को सूचीबद्ध करने का एक बेहतर तरीका है, /etc/passwdउन्हें वहां से पार्स करना और निकालना, और जहां वे हो सकते हैं, इसके बारे में कोई धारणा नहीं बनाना।

और आपकी दूसरी टिप्पणी को देखते हुए, आप वास्तव में उपयोगकर्ता के नाम चाहते हैं, न कि उनके घरेलू निर्देशिका, जिस स्थिति में, /etc/passwdवैसे भी एक बेहतर विकल्प है। ध्यान दें कि कुछ लिनक्स / यूनिक्स मशीनों में अन्य उपयोगकर्ता प्रमाणीकरण तंत्र कॉन्फ़िगर किए जाएंगे (जैसे LDAP), और इसलिए अंततः, आपकी क्वेरी पहले की तुलना में अधिक जटिल है, लेकिन आप /etc/passwdशुरू करने के लिए एक अच्छी जगह है।


9
getentसिस्टम पर भी देखें जो इसका समर्थन करते हैं।
Kusalananda

6
हां, getentहमेशा पार्स करने से बेहतर है /etc/passwd(यह "अन्य उपयोगकर्ता प्रमाणीकरण तंत्र" के साथ चिंता को संबोधित करता है)।
स्टीफन किट

@ कुसलानंद एक getentसमाधान के साथ समस्या यह है कि यह माना जाता है कि डेटा स्रोत को एन्यूमरेट किया जा सकता है, और केवल एक विशिष्ट मूल्य के लिए ही नहीं। इस सवाल का जवाब स्टैफेन चेज़लस में विस्तृत है , लेकिन मैं हालांकि इस पृष्ठ पर किसी के लिए भी एक टिप्पणी जोड़ूंगा
एंड्रयू हेनले

7

संक्षिप्त उत्तर :

compgen -u

मध्यम उत्तर : चूंकि आप उपयोग कर रहे हैं bash, आप ~उपयोग करने के लिए सभी संभावित पूर्णताओं को सूचीबद्ध कर सकते हैं compgen -A user। यह एक सामान्य उपयोग है, इसे संक्षिप्त किया जा सकता है compgen -u। शेल बिल्ड के रूप में, compgenअपना स्वयं का मैन पेज नहीं है। इसके बजाय डॉक्यूमेंटेशन के लिए बैश (1) देखें और प्रोग्रामेबल कम्पलीशन पर सेक्शन पढ़ें ।

एक अधिक गहन विकल्प

यदि आप पोर्टेबिलिटी के बारे में बेहद चिंतित हैं, तो आप अन्य मशीनों पर निर्भर होने में भी सक्षम नहीं हो सकते हैं bash। उस मामले में, यह करें:

(getent passwd ||
    dscl . -ls /Users dsAttrTypeNative:homeDirectory || 
    nidump passwd  ||
    cat /etc/passwd) 2>/dev/null  |  cut -d: -f6

स्पष्टीकरण लंबे उत्तर में सब कुछ करने की कोशिश करता है, इसलिए यह किसी भी यूनिक्स प्रणाली पर बहुत अधिक काम करेगा, चाहे वह नए /etc/nsswitch.conf का उपयोग करता हो (जीएनयू / लिनक्स और बीएसडी दोनों साथ आते हैं getent), पारंपरिक यूनिक्स पासबुक फ्लैट फ़ाइल, मैकओएस निर्देशिका Services ( dscl), या यहां तक ​​कि पुराने, बिल्ली-थीम वाले MacOS X रिलीज़ और नेक्स्टस्टेप ( nidump)।

सादगी लेकिन, आपको कितना पोर्टेबल चाहिए? यूनिक्स में चीजों को करने के कई तरीके हैं और कभी-कभी सरलता होती है। अगर आपको एक चुनना है, तो मैं getent passwd | cut -d: -f6शेल स्क्रिप्ट के लिए सुझाव दूंगा


फुटनोट I: मैंने MacOS का उपयोग किसी बिट में नहीं किया है, इसलिए यदि कोई मेरे लिए पुष्टि कर सकता है कि मुझे सिंटैक्स सही मिला है (और आउटपुट में कोई आवारा कॉलोन शामिल नहीं होगा जो गड़बड़ करेगा cut), तो यह बहुत अच्छा होगा। धन्यवाद।

फुटनोट What: मैं जो सुझाता हूं और जो मैं करता हूं वह अलग हो सकता है। व्यक्तिगत रूप से, मैं अधिक बार cut -d: -f1 /etc/passwdकमांड लाइन पर पारंपरिक का उपयोग करूँगा । दशकों के दोहराव के बाद, मेरी उंगलियां इसे टाइप कर सकती हैं, जबकि मेरा दिमाग अन्य चीजों पर काम कर रहा है।


2
सभी मैक ओएस एक्स मशीनों को बैश होने की बहुत गारंटी है, क्योंकि यह सिस्टम के साथ आता है। (जैसा कि zsh और कई अन्य गोले हैं।)
सिल्वरवुल्फ़ -

सही है, लेकिन जब मैं MacOS का उपयोग कर रहा था, तब Apple ने लंबे समय में अपडेट नहीं किया था और यह कुछ क्रस्टी संस्करण 3 चीज थी जिसे मुझे हमेशा बदलना पड़ा। क्या ऐपल ने बैश को अपडेट करने के बारे में बेहतर जानकारी दी है?
Hackerb9


सच है, उस बारे में नहीं सोचा था। बैश का मेरा संस्करण (macOS सिएरा 10.12.6) 3.2.57 है। (:
सिल्वरवॉल्फ -

वैसे भी, bashपड़ा है compgen -uके बाद से 2.04 2000 में जारी किया गया
स्टीफन Chazelas

2

किस बारे में ls -l ~/..? यह आपके घर निर्देशिका के माता-पिता की सभी निर्देशिकाओं को सूचीबद्ध करता है।


4
यह केवल उन प्रणालियों पर काम करता है जहां सभी होम डाइरेक्टरी एक ही डायरेक्टरी में आधारित होती हैं, जो कि बहुत सी नहीं हैं (आप सोच सकते हैं कि /homeलिनक्स सिस्टम पर आम है, लेकिन जब आप इसे चलाते हैं तो क्या होता है root?)। घर निर्देशिकाओं को सूचीबद्ध करना एक रोमांच से भरा हुआ है यदि आप उन सभी मामलों को संभालना चाहते हैं जो आपके पास आने की संभावना है, तो विवरण के लिए अन्य उत्तर देखें।
स्टीफन किट

7
यह यकीनन अब तक का एकमात्र जवाब है जो सीधे ओपी की कथित समस्या का जवाब देता है। हालांकि, यह ओपी की अंतर्निहित समस्या का जवाब नहीं देता है।
पाइप

1
इस उत्तर में मूल्य यह समझने में है कि यह क्या याद करता है, और क्यों यह अन्य उच्च-मतदान उत्तरों के समान अच्छा नहीं है।
क्रिग्गी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.