मुझे अपनी PATH में उपयोगकर्ता-लेखन योग्य निर्देशिका में अपनी स्क्रिप्ट को डाउनलोड करने और स्थापित करने के लिए किस कोड का उपयोग करना चाहिए (बिना sudo की आवश्यकता के)?


1

संपादित करें: जिन स्थानों पर मैंने $ HOME / .bin कहा था, मुझे $ HOME / बिन लिखना चाहिए था या कोई समकक्ष ठीक है। IE, कोई भी उपयोगकर्ता-योग्य निर्देशिका जो उपयोगकर्ता के PATH में है।

तो मेरे पास एक bash स्क्रिप्ट है जिसे मैं अपने API के लिए एक क्लाइंट के रूप में वितरित कर रहा हूं। वर्तमान संस्करण इस तरह से स्थापित होता है curl -s http://api.blah.com/install | sudo sh। मैं छह अलग-अलग पैकेज प्रबंधन प्रणालियों से निपटने की कोशिश कर सकता हूं ताकि वे बस apt-getया brew installकिसी बिंदु पर हो सकें , लेकिन अब मैं एक-लाइनर के साथ जा रहा हूं क्योंकि मैं चाहता हूं कि यह समाधान कई प्रणालियों के लिए काम करे। हालांकि, जाहिरा तौर पर साइबरविन या मैक जैसे सिस्टम पर काफी कम उपयोगकर्ता हैं, जिनके पास सूडो नहीं हैं या उन्होंने इसे स्थापित नहीं किया है।

परिदृश्य एक उपयोगकर्ता है जो मेरे एपीआई के लिए साइन अप करता है, उनके क्रेडिट कार्ड की जानकारी दर्ज करता है। मेरे पास एपीआई के लिए एक बैश क्लाइंट है जो एक संदर्भ कार्यान्वयन के रूप में दोगुना है और यह भी एक तरीका है कि एपीआई की कोशिश करें या कमांड लाइन का उपयोग करके वीएम और डॉक कंटेनर को तैनात करें। मैं एपीआई क्लाइंट स्थापित करने के लिए उपयोगकर्ताओं के लिए एक आसान तरीका बनाना चाहता हूं।

उदाहरण के लिए, npm के लिए एक-लाइन इंस्टॉल हुआ करता था curl http://npmjs.org/install.sh | sh। साथ ही होमब्रे में एक-लाइन इंस्टॉलर है ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"(देखें http://brew.sh )।

मेरी स्थापित स्क्रिप्ट बस एपीआई क्लाइंट स्क्रिप्ट को डाउनलोड करती है और इसे / usr / bin में डालती है और इसे निष्पादन योग्य बनाती है। लेकिन मैं सूडो और इस तथ्य के आधार पर सोच रहा हूं कि वास्तव में इसे विश्व स्तर पर स्थापित करने की आवश्यकता नहीं है, मैं इसे उपयोगकर्ता के $ HOME / .bin या $ HOME / लोकल / बिन (इसे बनाने के लिए) में स्थापित करना चाहूंगा। यदि यह कोई मौजूदा समतुल्य नहीं है)।

यह मेरी वर्तमान इंस्टॉल स्क्रिप्ट है:

#!/bin/bash
BASE="https://api.blah.com"

sudo bash -c "curl -s $BASE/mycmd > /usr/bin/mycmd"
sudo chmod uga+x /usr/bin/mycmd

पहली शिकन जो मुझे होती है, वह यह है कि कई उपयोगकर्ता अब zsh में हैं। इसलिए यदि मैं ~ / .bashrc में एक पंक्ति जोड़ या संशोधित करता हूं जो $ HOME / .bin को शामिल करने के लिए PATH को अपडेट करता है, जो उन प्रणालियों के लिए काम नहीं करेगा।

तो इस प्रश्न को शांत करने के लिए, मुझे उस उपयोगकर्ता के PATH ($ HOME / लोकल / बिन, या जो भी PATH में डिफ़ॉल्ट रूप से उपलब्ध है) डायरेक्टरी में अपनी स्क्रिप्ट को डाउनलोड करने और इंस्टॉल करने के लिए किस कोड का उपयोग करना चाहिए। उनके पेट में, आवश्यकता (या कम से कम मजबूत इच्छा) के साथ कि यह लगभग सभी की प्रणाली पर काम करेगा (यदि उनके पास यूनिक्स प्रॉम्प्ट जैसा कुछ है) (बिना सूडो की आवश्यकता के)?

चूँकि कुछ लोग PATH को बुराई करने के लिए संशोधित करने पर विचार करते हैं, मैं डिफ़ॉल्ट $ HOME / उस सिस्टम के लिए कुछ भी / बिन में स्थापित करना चाहूंगा, जो कि उपयोगकर्ता के PATH में पहले से ही है, यदि संभव हो तो, अपने PATH को अपने विशेष रूप से शामिल करने के लिए स्वचालित रूप से संशोधित करने के बजाय निर्देशिका।

बहुत बहुत धन्यवाद!


यहाँ देखें - यह आपके प्रश्न के भाग का उत्तर दे सकता है। इसके अलावा, commandशायद बेहतर है hash। वास्तव में, मुझे लगता है कि यह इसके सभी उत्तर देता है। unix.stackexchange.com/a/126854/52934
mikeserv

धन्यवाद mikeserv ऐसा लगता है जैसे आप सुझाव दे रहे हैं मुझे एक और समस्या है जो मैंने नहीं सोचा था - बैश का स्थान। अगर मैं इसे OSX, Linux और cygwin तक सीमित करता हूं, तो क्या मुझे अभी भी यह समस्या है? इसके अलावा, क्या यह सवाल / प्रतिक्रिया मेरे प्रश्न के किसी भी मुख्य पहलुओं का जवाब देती है, जैसे कि मुझे यह सुनिश्चित करना है कि मुझे उपयोगकर्ता के पेटी में एक निर्देशिका में स्थापित करना है बिना sudo की आवश्यकता के?
जेसन लिवेसे

मैं सुझाव नहीं दे रहा हूं कि शेल का स्थान समस्या है - मैं सुझाव दे रहा हूं कि मुख्य स्क्रिप्ट में कुछ भी हार्डकोड है समस्या है। बस एक स्क्रिप्ट लिखें जो आपके लिए आवश्यक मूल्यों को प्राप्त कर सकती है और फिर उस स्क्रिप्ट को फिर से लिखना होगा।
mikeserv

ठीक है, अब मैं देख रहा हूँ धन्यवाद। तो कोई भी विचार कि मैं किस तरह के कोड का उपयोग कर सकता / सकती हूं जो एक उपयोगकर्ता-योग्य निर्देशिका को निर्धारित / निर्धारित कर सकता है जो पहले से ही उनके पेट में है?
जेसन लिवेसे

ज़रूर cat > ./file || cd elsewhere- कि $PATHहालांकि पता नहीं है । माफ़ करना। लेकिन getconfवहां आपकी मदद कर सकता है। यह set -Cभी सुनिश्चित करेगा कि आप किसी भी चीज़ को ओवरराइट न करें।
mikeserv

जवाबों:


4

प्रोग्राम के लिए एक शब्द है जो उपयोगकर्ता के पर्यावरण के साथ खुद को इंजेक्ट करता है: वायरस।

बस ~ / बिन / (मैन्युअल रूप से स्थापित स्क्रिप्ट के लिए ऐतिहासिक वास्तविक तथ्य) या ~ / .Local / बिन / (एक गैर-रूट पैकेज प्रबंधक द्वारा स्थापित लिपियों के लिए आधुनिक, क्सीरिफॉर्मल, मानक) स्थापित करें। आमतौर पर, उपयोगकर्ता के अनुकूल डिस्ट्रोस पहले से ही $ PATH में एक या दोनों होंगे।

या बेहतर अभी तक, स्थापना उपसर्ग के लिए उपयोगकर्ता को तुरंत संकेत देता है।


1
वायरसों के संबंध में, क्या आप यह सुझाव दे रहे हैं कि 'वन-लाइन' स्थापित करने के लिए जैसा कि मैं यहां बता रहा हूं कि यह वायरस है या अन्यथा अवांछनीय है? यदि नहीं, तो आपका क्या मतलब है? मैंने विशेष रूप से आपसे दृष्टिकोण के बारे में नकारात्मक टिप्पणी नहीं करने के लिए कहा है। यदि आप मुझे ~ / बिन में स्थापित करने की इच्छा रखते हैं, तो मुझे वही समस्या है जो मैंने मूल रूप से की थी: जिसके लिए विशेषाधिकारों की आवश्यकता होती है, जैसे sudo। या कोई और तरीका है जिसकी आवश्यकता नहीं है sudo? तो ऐसा लगता है कि टिप्पणी रचनात्मक नहीं थी। ~ / .लोकल / बिन मुझे पता नहीं था। PATH में उपलब्ध डिफ़ॉल्ट के रूप में कौन से सिस्टम हैं? मुझे उबंटू के लिए पता है, इसके ~ / बिन।
जेसन लिवेसे

मैं अपनी स्क्रिप्ट को स्वचालित रूप से पथ में जोड़ना पसंद करूंगा, क्योंकि उपयोगकर्ता जब अपने क्रेडिट कार्ड के साथ मेरी सेवा के लिए साइन अप करने के बाद मेरी इंस्टॉल स्क्रिप्ट को चलाता है, तो यह एक वायरस से काफी दूर है। उन्हें प्रेरित करना एक असुविधा और अनावश्यक की तरह लगता है अगर मैं कोड बनाने का प्रबंधन कर सकता हूं जो फ़ाइल को $ HOME / dir में रखेगा जो पहले से ही मार्ग में है, या एक जोड़ें।
जेसन लिवेसे

1
यदि उपयोगकर्ता इसे सत्यापित किए बिना कुछ डाउनलोड करना चाहता है, तो यह उनकी समस्या है, इसलिए यह तब तक ठीक है जब तक स्क्रिप्ट वास्तव में बुराई नहीं है। PATH का संपादन बुराई पर आधारित होगा, चाहे वह कितना भी सुविधाजनक क्यों न हो; बस पढ़ें और चेतावनी दें।
o11c

2

आप स्क्रिप्ट में ही $ PATH की क्वेरी क्यों नहीं करते? जांचें कि क्या उपयोगकर्ता के पास अपने $ PATH में कोई निर्देशिका है जिसे वे (आमतौर पर, ~/binया ~/.local/bin) लिख सकते हैं । यदि वे करते हैं, महान, वहाँ स्थापित करें। यदि वे नहीं करते हैं, तो आप संकेत देते हैं। मेरा मानना ​​है कि कुछ डिस्ट्रोस, जैसे कि उबंटू, ~/bin$ PATH में स्वचालित रूप से जुड़ जाएगा यदि निर्देशिका मौजूद है, लेकिन आप यह नहीं मान सकते हैं कि हमेशा मामला हो।

आपके पास केवल एक ही विकल्प है कि आप $ PATH में जो भी डायरेक्टरी स्थापित करें उसे ~/.profileकई गोले द्वारा संपादित करके संपादित करें । के बारे में भूल जाओ ~/.bashrc, न केवल यह विशिष्ट बैश है, लेकिन $ PATH का कोई व्यवसाय नहीं है जहां पहली बार में स्थापित किया जा रहा है। हालाँकि, वैश्विक चरों का संपादन करना बहुत अच्छी बात नहीं है।

वास्तव में सबसे अच्छी बात यह है कि यदि कोई नहीं पाया गया है, तो उसे योग्य निर्देशिकाओं और संकेत के लिए जाँचना है।


2

शिंग करने के लिए सुरक्षा के दृष्टिकोण से, और अधिक सूक्ष्मता, एक मजबूती और त्रुटि से निपटने के दृष्टिकोण से संदिग्ध है ।

यदि आपकी स्थापित स्क्रिप्ट केवल 3 लाइनें है, तो उपयोगकर्ता को केवल उन 3 लाइनों को निष्पादित क्यों नहीं करना है? वे पहले से ही आपके curlआदेश को कॉपी-पेस्ट कर रहे हैं, और लाइन बना रहे हैं कि वे कॉपी-एंड-पेस्ट कर रहे हैं और आपको थोड़ी देर चिपकाने देंगे:

mkdir -p ~/bin && curl -s "https://api.blah.com/mycmd" > ~/bin/mycmd && chmod ugo+x ~/bin/mycmd

अधिकांश डिस्ट्रोस ~/bin/पर $PATH, तब तक डाला जाता है , जब तक कि निर्देशिका मौजूद है। सबसे खराब रूप से, आपके उपयोगकर्ताओं को अपनी निर्देशिका में जोड़े जाने के लिए लॉग आउट करने और वापस जाने की आवश्यकता हो सकती है $PATH। यहां तक ​​कि अगर यह उनके में नहीं है $PATH, तो आप लोगों को बता सकते हैं कि ~/bin/mycmdइसके बजाय बस चलाने के लिए mycmd। यदि वे यूनिक्स-प्रेमी पर्याप्त हैं, तो उन्हें पता चल जाएगा कि वे सुनिश्चित कर सकते हैं कि ~/bin/उनके रास्ते में है, और अतिरिक्त 6 वर्णों को छोड़ दें। यदि वे यूनिक्स-प्रेमी नहीं हैं, और उनका डिस्ट्रोफिल अनहेल्दी है, तो उन्हें 6 अतिरिक्त अक्षर लिखने होंगे - शायद यह कोई बड़ी बात नहीं है।

और अगर किसी के पास रूट है और उसके अलावा कहीं और स्थापित करना चाहता है ~/bin/, तो ऐसा करने के लिए उपरोक्त लाइन को बदलना आसान है - और अगर उन्हें समझ में नहीं आता है कि कैसे परिवर्तन करना है, तो उन्हें रूट फाइल सिस्टम को बदलना नहीं चाहिए!


0

मैंने उन्हें अपने "गेटिंग स्टार्ट" पृष्ठ पर दो विकल्प दिए। मैं संक्षेप में समझाता हूं कि इंस्टॉलर स्क्रिप्ट क्या करती है, जैसे ~ / .लोकल / बिन या लाइक और फिर संभावित रूप से PATH को ~ / .zshrc या ~ / .bashrc में जोड़ना। मैं उन्हें स्क्रिप्ट का उपयोग करने के बजाय मैन्युअल रूप से इंस्टॉल करने का विकल्प भी देता हूं, ऐसा करने के लिए सरल निर्देशों के साथ।

स्वचालित इंस्टॉलर को चलाने के लिए उपयोगकर्ता इस तरह एक कमांड पेस्ट और निष्पादित करेगा:

curl -s https://thesite.com/installmycmd > /tmp/inst; source /tmp/inst

यह installmycmd स्क्रिप्ट है:

#!/bin/bash

BASE="https://thesite.com"

declare -a binddirs
bindirs=($HOME/bin $HOME/.local/bin $HOME/.bin)

founddir="false"

findprofile() {
  profiles=($HOME/.zshrc $HOME/.bashrc $HOME/.bash_login $HOME/.login $HOME/.profile)
  for prof in "${profiles[@]}"; do
    if [ -f "$prof" ]; then
      echo "$prof"
      return
    fi
  done
  touch $HOME/.profile
  echo "$HOME/.profile"
}

for bindir in "${bindirs[@]}"; do
  if [ -d "$bindir" ]; then
    founddir=true
    echo "You have a user bin dir here $bindir."
    whichprofile=$(findprofile)
    pathline=$(grep ^PATH= $whichprofile)
    if [[ ! $pathline == *$bindir* ]]; then
      echo "Appending $bindir to PATH in $whichprofile"
      echo -e "\nexport PATH=\$PATH:$bindir" >> "$whichprofile"
      NEWPATH=$PATH:$bindir      
      export NEWPATH
    else
      echo "That is in your PATH in $whichprofile"
    fi
    break;
  fi
done

if [ ! -z $NEWPATH ]; then
  echo "Exported PATH: $NEWPATH" 
  export PATH=$NEWPATH
fi

if [[ "$founddir" == "false" ]]; then
  echo "Could not find ~/.bin or ~/.local/bin or ~/bin."
  echo "Creating ~/.local/bin and adding to PATH"

  mkdir -p $HOME/.local/bin
  bindir=$HOME/.local/bin

  whichprofile=$(findprofile)
  echo "Appending PATH edit to $whichprofile"

  echo -e "\nexport PATH=$PATH:$HOME/.local/bin" >> "$whichprofile"
  export PATH=$PATH:$HOME/.local/bin
fi

bash -c "curl -s $BASE/JSON.sh > $bindir/JSON.sh"
bash -c "curl -s $BASE/mycmd > $bindir/mycmd"
chmod ug+x $bindir/mycmd
chmod ug+x $bindir/JSON.sh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.