2 पॉइंट द्वारा GN⁺ 2024-06-24 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • Unix उपयोगकर्ता जब ~/bin/ में निजी scripts रखकर उसे PATH में जोड़ते हैं, तो छोटे command names नई system commands से टकरा सकते हैं
  • Debian/Ubuntu जैसे बहुत सारे commands देने वाले environments में जोखिम और बढ़ जाता है; उदाहरण वाले Ubuntu laptop के /usr/bin commands की गिनती 21,733 निकली
  • निजी commands के आगे कॉमा (,) लगाने पर shell और tools इसे सामान्य filename character की तरह treat करते हैं, फिर भी system commands से अलग पहचानना आसान रहता है
  • कॉमा Shift के बिना type किया जा सकता है, और shell में मजबूत meaning रखने वाले parentheses, backslash, colon, backtick, single quote, slash और dot की तुलना में collision की गुंजाइश कम होती है
  • , के बाद Tab दबाने पर निजी commands की list तुरंत देखी जा सकती है, जिससे ~/bin/ command names को साफ-सुथरा रखना आसान होता है

निजी command names क्यों टकराते हैं

  • कई Unix users home directory में ~/bin/ बनाते हैं और उसे PATH में जोड़कर निजी सुविधा commands और shell scripts इस्तेमाल करते हैं
  • समस्या यह है कि निजी script names आमतौर पर छोटे lowercase combinations होते हैं, इसलिए वे default system commands जैसे दिखने लगते हैं
  • अगर Linux distribution कोई नया command जोड़ता है, तो उसका नाम संयोग से किसी मौजूदा निजी command जैसा हो सकता है
  • Debian-परिवार के environments में उपलब्ध commands की संख्या ज्यादा होने से यह समस्या ज्यादा वास्तविक लगती है
    • उदाहरण वाले Ubuntu laptop में /usr/bin के ठीक नीचे commands गिनने पर 21,733 मिलते हैं
    • apt-file search -x '^/usr/bin/[^/]*$' | wc -l

कॉमा prefix के फायदे

  • समाधान यह है कि निजी command names को ऐसे रूप में बदला जाए जो type करने में आसान हो, लेकिन system command name के रूप में आम तौर पर चुना न जाता हो
  • typing सुविधा का मानदंड है Shift key का इस्तेमाल न करना, और इस शर्त को पूरा करते हुए सुरक्षित characters बहुत ज्यादा नहीं हैं
    • lowercase letters पहले से ही system commands में आम हैं
    • parentheses, backslash, colon, backtick और single quote का shell में special meaning होता है
    • slash directory separator है, इसलिए filename में नहीं आ सकता
    • dot filename की शुरुआत में hidden file को दर्शाता है, और दूसरी जगहों पर भी extension अलग करने के लिए अक्सर इस्तेमाल होता है
  • बचा हुआ विकल्प सरल कॉमा (,) है, और आसपास के tools व shell कॉमा को filename के अंदर सामान्य character की तरह treat करते हैं
  • हर निजी command में prefix के रूप में कॉमा लगाने से वे system commands से साफ अलग हो जाते हैं और name collisions से बचना आसान होता है
  • Tab completion के साथ इस्तेमाल करने पर , type करने के बाद निजी commands की list तुरंत देखी जा सकती है
    • उदाहरण list में ,complete-scp, ,complete-ssh, ,coreoff, ,coreon, ,find, ,go-thpgp, ,gr, ,hss, ,mount-thpgp, ,mount-twt, ,range, ,svn-store-password, ,umount आदि शामिल हैं
  • यह तरीका करीब 10 साल से इस्तेमाल किया जा रहा है और निजी ~/bin/ command names को साफ-सुथरे ढंग से व्यवस्थित रखने के तरीके के रूप में recommend किया जाता है

2 टिप्पणियां

 
GN⁺ 2024-06-24
Hacker News टिप्पणियाँ
  • सिर्फ़ शीर्षक देखकर लगा था कि यह एक भयानक आइडिया होगा, लेकिन असल में यह काफ़ी पसंद आया। खासकर Tab के ज़रिए अपने सारे tools को लिस्ट करने वाला हिस्सा अच्छा लगा।
    हाल के दिनों में मुझे namespace conflict ज़्यादा नहीं झेलने पड़े हैं, और management role में जाने के बाद मेरी technical sharpness थोड़ी ढीली पड़ी है, यह भी सच है। मेरा tech stack लगभग 10 साल पुराना महसूस होता है, इसलिए सोचता हूँ कि फिर से up-to-date होने की शुरुआत कहाँ से करूँ

    • आजकल का बढ़िया तरीका शायद यह है कि खाली समय में खुद कुछ बनाओ, और बनाते-बनाते स्वाभाविक रूप से सीखो। आत्मनिर्भरता, creativity, और self-starting attitude आजकल की vibe है, और जितना ज़्यादा बनाते हो, उतनी ही असली समस्याएँ सुलझाने की समझ और नए समाधान खुद खोजने की motivation मिलती है
    • मैं भी management side में हूँ, और मुझे भी लगता है कि अगर लगातार बने न रहो तो skills पीछे छूटने लगती हैं।
      मेरा तरीका यह है कि मैं ऐसे tools खुद बनाता हूँ जो मेरी ज़िंदगी आसान करें। उदाहरण के लिए, अगर कंपनी में कोई web service साधारण lookup के लिए बार-बार इस्तेमाल होती है, तो मैं देखता हूँ कि उसका API है या नहीं, और रोज़मर्रा के काम तेज़ करने के लिए CLI लिख लेता हूँ। उसे अपनी पसंद के हिसाब से polish करने के बाद टीम के साथ share करता हूँ, लेकिन दूसरों को उसे अपनाने के लिए मनाना मुश्किल होता है। फिर भी मैं उसे हर दिन इस्तेमाल करता हूँ, इसलिए ज़्यादा परवाह नहीं करता
    • इसी वजह से मैंने काम में इस्तेमाल होने वाले परिचित stack की जगह ज़्यादा trendy अलग stack में एक side project बनाया।
      मकसद यह था कि नए नज़रिए दिखें और trends पर बातचीत कर सकूँ, और उनमें से कुछ अब काम में भी आ चुके हैं। इससे पुराने components को भी और गहराई से समझने में मदद मिली
  • मुझे सच में समझ नहीं आता कि यहाँ समस्या क्या है। अपना bin directory बस $PATH के अंत में नहीं, शुरुआत में रख दो। अपने commands देखना हों तो बस ls ~/bin चला लो

    • लेकिन फिर कोई tool यह मानकर चलता है कि $0 system path में है, और वह टूट जाता है, जिसके बाद परेशान करने वाली debugging शुरू हो सकती है।
      आख़िर में यह बस इस बात का सवाल है कि कौन-सा ज़हर चुनना है
    • क्या बस अपने दिए हुए नाम याद नहीं रखे जा सकते? समझ नहीं आता कि इसे किसी तरह का hack क्यों माना जा रहा है
    • एक फ़ायदा यह है कि fzf autocomplete इस्तेमाल किया जा सकता है। उदाहरण के लिए fish में command का पहला अक्षर टाइप करके Tab दबाओ तो fzf खुल सकता है।
      तब सिर्फ़ ,+Tab से custom commands जल्दी filter किए जा सकते हैं। इसके मुकाबले ls ~/bin में, जबकि यह काम अक्सर किया जाता है, टाइप करने के लिए काफ़ी ज़्यादा लिखना पड़ता है, या फिर ls+ऊपर वाला arrow कई बार दबाकर पहले autocomplete तक पहुँचना पड़ सकता है
    • ls ~/bin, , की तुलना में टाइप करने में बहुत धीमा है
  • मैं git के लिए एक thin wrapper में aa, st, di, dp, cm, le जैसे छोटे custom command names इस्तेमाल करता हूँ।
    इनमें से एक सचमुच किसी utility से टकराता है जो कुछ systems पर default install होती है। फिर भी मेरा bin directory system directories से पहले $PATH में है, इसलिए मेरी command जीत जाती है, और उस टकराने वाले tool में मेरी ख़ास दिलचस्पी भी नहीं है। अगर कोई और उपयोगी tool मेरे tool से टकराए, तो मैं शायद अपने tool का नाम बदलने के बजाय उस दूसरे tool को कोई non-conflicting alias दे दूँ। ये दो-अक्षरी tools बहुत सुविधाजनक हैं

    • इस तरह का setup ऐसी समस्या तक ले जा सकता है जहाँ apt-get upgrade Dwarf Fortress चला दे।
      https://askubuntu.com/questions/938606/dwarf-fortress-starti...
    • सही बात है। 1 से 3 अक्षरों वाले नाम user aliases, functions, scripts, और standard utilities के लिए बचाकर रखने चाहिए
    • मेरे git aliases ज़्यादातर g से शुरू होने वाले दो-अक्षरी combinations होते हैं। जैसे gs का मतलब git status है।
      लेकिन कभी-कभी सच में GhostScript की ज़रूरत पड़ती है। जैसे PDF files में fonts embed करते समय यह बहुत बढ़िया है। आम तौर पर तब मैं env gs इस्तेमाल करता हूँ
    • मेरी सारी personal commands j से शुरू होती हैं। java आने पर यह काफ़ी मज़ेदार हो गया था। comma इस्तेमाल करना काफ़ी दिलचस्प idea है।
      फिर भी अच्छा है कि मैंने k से शुरू नहीं किया, KDE की वजह से :)
    • मेरी थोड़ी मज़बूत राय है कि system commands उतनी आसानी से accessible नहीं होनी चाहिए जितनी user commands होती हैं। किसी न किसी रूप में namespace होना चाहिए।
      उदाहरण के लिए, मेरे हिसाब से mkfs को sys::mkfs जैसी किसी चीज़ के रूप में चलाना चाहिए। system commands और user commands के बीच की रेखा कई तरीकों से तय की जा सकती है, और कुछ धुंधले हिस्से भी होंगे, लेकिन अगर कोई command ऐसी है जिसे user न तो जानता है और न ही उसने explicitly install किया है, फिर भी वह गलती से चल सकती है, तो उसे global namespace में सीधे expose नहीं होना चाहिए
  • एक संबंधित सवाल है
    मैं ज़्यादातर Windows इस्तेमाल करता हूँ, और लेखक की तरह Python-केंद्रित कई CLI scripts बनाकर उन्हें ~/bin/ के समकक्ष किसी जगह रखता हूँ। अगर python.exe को .py extension के लिए default program सेट कर दिया जाए और .py को %pathext% में जोड़ दिया जाए, तो किसी भी path से सिर्फ hello टाइप करके ~/bin/hello.py चला सकता हूँ, और मैं ऐसा दिन में सैकड़ों बार करता हूँ। आजकल Linux ज़्यादा इस्तेमाल कर रहा हूँ, लेकिन अभी भी नया हूँ इसलिए वैसा ही सेटअप नहीं बना पाया। Linux में शायद “associated program” जैसा concept नहीं है, इसलिए .py file को सीधे call करके shell से Python में run नहीं करा सकता। हाँ, script पर chmod +x दे सकता हूँ, लेकिन तब script में shebang डालना पड़ता है, जो hardcoding जैसा लगता है और असुविधाजनक है। बाद में अगर .py script को /usr/bin/python की जगह /usr/bin/nohtyp से चलाना चाहूँ तो? और script को call करते समय .py हिस्सा छोड़ने का तरीका भी नहीं मिला। Linux की design की आलोचना नहीं कर रहा, उसके बहुत फायदे हैं, लेकिन मैं सचमुच $PATH में मौजूद hello.py को hello की तरह चलाना चाहता हूँ

    • Linux में अब भी shebang ही इस समस्या के लिए सही tool है। हल्का तरीका चाहिए तो path में my_python symbolic link रखिए, और shebang को /usr/bin/env my_python लिखिए
      अगर ज़्यादा सिद्धांतपरक तरीका चाहिए तो update-alternatives tool देखिए। यह इस तरह की abstraction को और सामान्य रूप से देता है: https://linuxconfig.org/how-to-set-default-programs-using-up...
    • समाधान तो दूसरे लोग बता ही चुके हैं, लेकिन क्यों ऐसा है इस पर एक बात जोड़ना चाहता हूँ
      Linux में, और वास्तव में Windows को छोड़ अधिकांश platforms पर, file extension का महत्व बहुत कम होता है। किसी भी तरह की executable file का चलना extension से नहीं बल्कि +x flag जैसी चीज़ों से तय होता है। इसकी वजह से implementation language बदलकर दोबारा लिखने पर भी calling side नहीं टूटती। .py extension का अर्थ import की जाने वाली modules के लिए होता है; executable scripts के लिए ज़रूरत पड़ने पर shebang देखा जाता है। बाहरी distribution scripts आम तौर पर #!/usr/bin/env python इस्तेमाल करती हैं, और distribution package में शामिल scripts को अक्सर #!/usr/bin/python आदि से overwrite किया जाता है। shebang कई arguments support नहीं करता, लेकिन GNU env इसे नकल करने के लिए -S argument देता है। हालांकि argument length की समस्या फिर भी रहती है
    • file name से बस .py हटा दीजिए। उसे "hello" कहना पूरी तरह ठीक है
      shebang का कोई खास नुकसान याद नहीं आता। अगर सचमुच किसी दूसरे interpreter से चलाना हो, तो "nohtyp hello" की तरह explicitly चला सकते हैं। फिर भी अगर यह बहुत खलता है, तो shell startup file में alias define कर सकते हैं। उदाहरण के लिए bash में alias hello="python3 /path/to/hello.py" जैसा। चाहें तो किसी directory की contents के लिए ऐसे aliases अपने-आप बनाने वाली छोटी script भी लिख सकते हैं
    • ऐसा concept है, लेकिन shell syntax के भीतर नहीं। आम तौर पर यह desktop/GUI को सौंपा गया application-level मसला है
      shell scripts में आम तौर पर shebang जोड़कर और file को executable बनाकर, executable को script के भीतर ही घोषित किया जाता है। shebang को एक तरह के file extension की तरह समझ सकते हैं। chmod +x ./malware.py के बाद ./malware.py काम न करे, तो shebang जिस path की ओर इशारा कर रहा है उसे देखिए। अगर interpreter script को सामान्य argument की तरह चला सकता है, तो xdg-open malware.py जैसी तरह से भी मिलता-जुलता व्यवहार बनाया जा सकता है। यह default file manager में double-click करने जैसा होगा। Linux को मुख्य desktop OS की तरह इस्तेमाल करते समय मैंने xop नाम का alias रखा था, लेकिन उसे सिर्फ image या document जैसी data files के लिए इस्तेमाल किया, जहाँ default behavior पहले से सही होता है। executable scripts के लिए default program को interpreter बनाना recommend नहीं करूँगा। हो सकता है आप default रूप से script चलाने के बजाय उसे editor में खोलना चाहें। मुझे लगता है xdg-open Gnome की ओर का tool है, लेकिन इसका मतलब यह नहीं कि दूसरे desktops पर इसका उपयोग नहीं हो सकता; मैंने इसे Xubuntu में भी इस्तेमाल किया है। अगर आप सचमुच चाहते हैं कि सभी Python files GUI context में भी default रूप से run हों, तो वह default सेट किया जा सकता है, लेकिन man xdg-open मददगार हो सकता है। फिर भी, यह अच्छी सलाह नहीं है
    • यह आपके लक्ष्य को सीधे पूरा नहीं करता, लेकिन shebang आधा ही hardcoded होता है। shebang इस्तेमाल करने का “सही” तरीका, कुछ सावधानियाँ https://unix.stackexchange.com/a/29620 में दी गई हैं, #!/usr/bin/env python है
      इससे path में सबसे पहले मिलने वाला python चलाया जाएगा। अगर बाद में आप /usr/bin/python की जगह /usr/bin/nohtyp से चलाना चाहें, तो /usr/bin से पहले search होने वाली directory में /usr/bin/nohtyp की ओर इशारा करता python symbolic link बना सकते हैं। उदाहरण के लिए, ~/myCommandPreferences को $PATH के आगे जोड़ सकते हैं
  • $PATH conflict से बचने का दूसरा तरीका यह है कि बहुत लंबा executable name रखा जाए, जिसे किसी और executable के इस्तेमाल करने की संभावना कम हो, और bashrc में उसके लिए छोटा alias रखा जाए
    alias का असर scripts के भीतर call की जाने वाली executables पर नहीं पड़ेगा, और मैं अपनी scripts में लंबे नाम से ही refer करता रह सकता हूँ। कमी यह है कि वैसी tab autocomplete usability नहीं मिलती, और वह हिस्सा सच में काफ़ी बढ़िया है। Python की venv activation script जैसी scripts, जिन्हें child process की तरह चलाने के बजाय source किया जाना चाहिए, उनमें फिर भी conflict हो सकता है, लेकिन ऐसे मामले कम होते हैं

    • zsh में वह autocomplete भी हो जाती है
  • comma से शुरू करने का तरीका text expander/text replacement community में भी आम है

    • सही। मेरे ज़्यादातर vim aliases भी , से शुरू होते हैं
  • हाल ही में ~/.local/bin/ देखते समय मुझे दर्जनों executables मिले जिन्हें मैंने वहाँ रखा हो, ऐसा मुझे याद नहीं था
    उनमें ज़्यादातर pyside से जुड़े थे, लेकिन कुछ दूसरी scripts भी थीं। कौन-सी script मैंने खुद लिखी थी और कौन-सी किसी और ने बनाई थी, यह याद करने के लिए मुझे एक-एक खोलकर देखना पड़ा। अगर मेरी scripts के नाम comma से शुरू होते, तो यह बहुत जल्दी हो जाता, और हर script क्यों बनाई थी यह भी उसे खोले बिना याद करने में मदद मिलती

    • आम तौर पर ~/.local/bin/ installed scripts के लिए होता है, और locally खुद लिखी गई चीज़ें ~/bin/ में रखी जाती हैं
  • मैं ऐसा नहीं करूँगा। अपना personal bin $PATH के आगे रख लें, और जब किसी shadow हुए प्रोग्राम को refer करना हो तो /usr/bin या /bin इस्तेमाल किया जा सकता है
    personalized tools की सूची ~/bin/[Tab] से दिखाई जा सकती है

    • मैं system utility को अपनी वाली से shadow करते हुए भी वही नाम इस्तेमाल करने में हिचकता नहीं, इसलिए यह समझ नहीं आता कि हर बार comma याद रखने की ज़रूरत क्यों हो
      अगर मुझे system का grep, जैसे Solaris grep, पसंद नहीं है और मैं अपनी पसंद का GNU grep इस्तेमाल करना चाहता हूँ, तो उसे बस grep ही क्यों न रहने दूँ?
  • 5 साल पहले यह आइडिया देखने की वजह से मैं अपने shell tricks के संग्रह में व्यवस्था ला सका। aliases और ~/bin को मिलाकर अब comma commands 50 से ज़्यादा हैं, और पहले की उलझी हुई हालत की तुलना में shell life बहुत ज़्यादा smooth हो गई है

  • 2020 में भी इस पर चर्चा हुई थी: https://news.ycombinator.com/item?id=22778988 (90 comments)

 
kayws426 2024-06-24

'_' का इस्तेमाल करना कैसा रहेगा?