বাশে কীভাবে ম্যানুয়ালি একটি বিশেষ ভেরিয়েবল (উদাহরণ: il টিলডে) প্রসারিত করবেন


135

আমার বাশ স্ক্রিপ্টে আমার একটি পরিবর্তনশীল আছে যার মান এইরকম:

~/a/b/c

মনে রাখবেন এটি তিলদে অপরিবর্তিত। আমি যখন এই ভেরিয়েবলটির উপর ls -lt করি (এটিকে $ VAR কল করুন), আমি এই জাতীয় ডিরেক্টরি পাই না। আমি বাশকে এই পরিবর্তনশীলটি কার্যকর না করেই ব্যাখ্যা / প্রসারিত করতে চাই। অন্য কথায়, আমি বাশকে ইভাল চালাতে চাই তবে মূল্যায়িত কমান্ডটি চালাতে চাই না। ব্যাশে এটা কি সম্ভব?

আমি কীভাবে এটিকে আমার স্ক্রিপ্টে ছাড়িয়ে না দিয়ে পরিচালনা করেছি? আমি দ্বিগুণ উদ্ধৃতি দিয়ে চারপাশে যুক্তিটি পাস করেছি।

আমার অর্থটি বোঝার জন্য এই আদেশটি ব্যবহার করে দেখুন:

ls -lt "~"

আমি ঠিক ঠিক এই অবস্থাতেই আছি I টিল্ডটি আরও প্রসারিত করতে চাই। অন্য কথায়, এই দুটি কমান্ডকে অভিন্ন করার জন্য আমার যাদুতে কী প্রতিস্থাপন করা উচিত:

ls -lt ~/abc/def/ghi

এবং

ls -lt $(magic "~/abc/def/ghi")

নোট করুন যে ~ / abc / def / ghi থাকতে পারে বা থাকতে পারে না।


4
আপনি কোয়েডগুলিতে টিলডে সম্প্রসারণও সহায়ক বলে মনে করতে পারেন। এটি বেশিরভাগ ক্ষেত্রেই, তবে পুরোপুরি নয়, ব্যবহার এড়ানো যায় eval
জোনাথন লেফলার

2
আপনার চলকটি কীভাবে একটি অপ্রস্তুত টিলডের সাহায্যে নিয়োগ পেয়েছে? সম্ভবত যা প্রয়োজন তা হ'ল টিড্ডের বাইরের কোটগুলির সাথে সেই পরিবর্তনশীল বরাদ্দ করা। foo=~/"$filepath"বাfoo="$HOME/$filepath"
চাদ সিকিটার

dir="$(readlink -f "$dir")"
জ্যাক ওয়াসে

উত্তর:


98

স্ট্যাক ওভারফ্লোর প্রকৃতির কারণে, আমি এই উত্তরটি কেবল অগ্রহণযোগ্য করে তুলতে পারি না, তবে মধ্যবর্তী পাঁচ বছরে আমি যেহেতু এটি পোস্ট করেছি সেখানে আমার স্বীকৃত প্রাথমিক এবং সুন্দর খারাপ উত্তরের চেয়ে অনেক বেশি ভাল উত্তর এসেছে (আমি তরুণ ছিলাম, হত্যা করব না) আমাকে).

এই থ্রেডের অন্যান্য সমাধানগুলি নিরাপদ এবং আরও ভাল সমাধান। প্রায়শই, আমি এই দু'জনের কোনওটির সাথে যাব:


Answerতিহাসিক উদ্দেশ্যে মূল উত্তর (তবে দয়া করে এটি ব্যবহার করবেন না)

যদি আমি ভুল না হয়ে থাকি তবে "~"বাশ স্ক্রিপ্ট দ্বারা সেভাবে প্রসারিত হবে না কারণ এটি আক্ষরিক স্ট্রিং হিসাবে বিবেচিত হয় "~"। আপনি এর মাধ্যমে প্রসারিত করতে বাধ্য করতে পারেন eval

#!/bin/bash

homedir=~
eval homedir=$homedir
echo $homedir # prints home path

বিকল্পভাবে, ${HOME}ব্যবহারকারীর হোম ডিরেক্টরি চাইলে কেবল ব্যবহার করুন use


3
যখন ভেরিয়েবলের মধ্যে একটি স্থান থাকে তখন আপনার কি একটি স্থিরতা রয়েছে?
হুগো

34
আমি ${HOME}সবচেয়ে আকর্ষণীয় পেয়েছি । এটিকে আপনার প্রাথমিক প্রস্তাবনা না দেওয়ার কোনও কারণ আছে কি? যাই হোক না কেন, ধন্যবাদ!
ঋষি

1
+1 - আমার the ~ কারও অন্য_উজার এবং ইউল কাজগুলি বাড়ানোর দরকার ছিল যখন OME হোম কাজ করবে না কারণ আমার বর্তমান ব্যবহারকারীর বাড়ির দরকার নেই।
অলিভকোডার

11
ব্যবহার evalকরা একটি ভয়াবহ পরামর্শ, এটি সত্যিই খারাপ যে এটি এতগুলি উপার্জন পায়। যখন ভেরিয়েবলের মানটিতে শেল মেটা অক্ষর থাকে তখন আপনি সমস্ত ধরণের সমস্যার মধ্যে চলে যাবেন।
ব্যবহারকারী2719058

1
আমি তখন আমার মন্তব্যটি শেষ করতে পারিনি এবং তারপরে, আমাকে এটি পরে সম্পাদনা করার অনুমতি দেওয়া হয়নি। সুতরাং আমি এই সমাধানটির জন্য কৃতজ্ঞ (আবার @ বিবিরি) ধন্যবাদ কারণ এটি আমার নির্দিষ্ট প্রসঙ্গে সেই সময়টিতে সহায়তা করেছিল। আমাকে সচেতন করার জন্য চার্লসকে ধন্যবাদ জানাই।
অলিভকোডার 26'15

114

যদি ভেরিয়েবলটি varব্যবহারকারী দ্বারা ইনপুট হয় তবে টিল্ড ব্যবহার করে প্রসারিত করা evalউচিত নয়

eval var=$var  # Do not use this!

কারণটি হ'ল: ব্যবহারকারী দুর্ঘটনাক্রমে (বা উদ্দেশ্য করে) উদাহরণ var="$(rm -rf $HOME/)"দিয়েছিলেন সম্ভাব্য বিপর্যয়কর পরিণতি সহ।

বাশ প্যারামিটার সম্প্রসারণ ব্যবহার করা একটি আরও ভাল (এবং নিরাপদ) উপায়:

var="${var/#\~/$HOME}"

8
আপনি কীভাবে কেবল ~ / এর পরিবর্তে ~ ব্যবহারকারীর নাম / পরিবর্তন করতে পারেন?
aspergillusOryzae

3
উদ্দেশ্য কি #মধ্যে "${var/#\~/$HOME}"?
জাহিদ

3
@ জাহিদ এটি ম্যানুয়ালটিতে ব্যাখ্যা করা হয়েছে । এটি টিলডকে কেবল শুরুতে ম্যাচ করতে বাধ্য করে $var
হ্যাকন হাগল্যান্ড

1
ধন্যবাদ। (1) কেন আমাদের \~পলায়ন দরকার ~? (২) আপনার জবাব অনুমান করে যে ~এটি প্রথম চরিত্র $var। আমরা কীভাবে শীর্ষস্থানীয় সাদা জায়গাগুলি উপেক্ষা করতে পারি $var?
টিম

1
@ টিম মন্তব্যের জন্য ধন্যবাদ। হ্যাঁ আপনি ঠিকই বলেছেন, যদি না এটি উদ্ধৃত স্ট্রিংয়ের প্রথম চরিত্র না হয় বা এটি একটি অব্যক্ত স্ট্রিংয়ে অনুসরণ :না করে তবে আমাদের টিলডে পালানোর দরকার নেই। ডক্সে আরও তথ্য । শীর্ষস্থানীয় সাদা স্থান অপসারণ করতে দেখুন, কোনও ব্যাশ ভেরিয়েবল থেকে
হ্যাকন হাগল্যান্ড 5:58

24

কোনও পূর্ববর্তী উত্তর থেকে নিজেকে প্লাগারাইজিং , এর সাথে সম্পর্কিত সুরক্ষা ঝুঁকি ছাড়াই দৃ rob়তার সাথে এটি করতে eval:

expandPath() {
  local path
  local -a pathElements resultPathElements
  IFS=':' read -r -a pathElements <<<"$1"
  : "${pathElements[@]}"
  for path in "${pathElements[@]}"; do
    : "$path"
    case $path in
      "~+"/*)
        path=$PWD/${path#"~+/"}
        ;;
      "~-"/*)
        path=$OLDPWD/${path#"~-/"}
        ;;
      "~"/*)
        path=$HOME/${path#"~/"}
        ;;
      "~"*)
        username=${path%%/*}
        username=${username#"~"}
        IFS=: read -r _ _ _ _ _ homedir _ < <(getent passwd "$username")
        if [[ $path = */* ]]; then
          path=${homedir}/${path#*/}
        else
          path=$homedir
        fi
        ;;
    esac
    resultPathElements+=( "$path" )
  done
  local result
  printf -v result '%s:' "${resultPathElements[@]}"
  printf '%s\n' "${result%:}"
}

...হিসাবে ব্যবহার...

path=$(expandPath '~/hello')

পর্যায়ক্রমে, একটি সহজ পদ্ধতির যা evalসাবধানতার সাথে ব্যবহার করে :

expandPath() {
  case $1 in
    ~[+-]*)
      local content content_q
      printf -v content_q '%q' "${1:2}"
      eval "content=${1:0:2}${content_q}"
      printf '%s\n' "$content"
      ;;
    ~*)
      local content content_q
      printf -v content_q '%q' "${1:1}"
      eval "content=~${content_q}"
      printf '%s\n' "$content"
      ;;
    *)
      printf '%s\n' "$1"
      ;;
  esac
}

4
আপনার কোডটি দেখে মনে হচ্ছে আপনি কোনও মশা মারতে কামান ব্যবহার করছেন। সেখানে পেয়েছিলাম অনেক বেশী সাদাসিধে উপায় হতে ..
Gino

2
@ জিনো, অবশ্যই একটি সহজ উপায় আছে; প্রশ্নটি হ'ল এটি সহজ উপায় যে এটিও নিরাপদ।
চার্লস ডাফি

2
@ জিনো, ... আমি মনে করি যে printf %qটিল্ড ছাড়া সমস্ত কিছু থেকে বাঁচতে কেউ ব্যবহার করতে পারে এবং তারপরেওeval ঝুঁকি ছাড়াই ব্যবহার করতে পারে।
চার্লস ডাফি

1
@ জিনো, ... এবং তাই প্রয়োগ করা হয়েছে।
চার্লস ডাফি

2
নিরাপদ, হ্যাঁ, তবে খুব অসম্পূর্ণ। আমার কোড এটি মজাদার জন্য জটিল নয় - এটি জটিল কারণ টিলডে সম্প্রসারণের মাধ্যমে করা প্রকৃত ক্রিয়াকলাপগুলি জটিল।
চার্লস ডাফি

10

ব্যবহারের Eval নেওয়ার জন্য একটি নিরাপদ উপায় "$(printf "~/%q" "$dangerous_path")"। নোট যে বাশ নির্দিষ্ট।

#!/bin/bash

relativepath=a/b/c
eval homedir="$(printf "~/%q" "$relativepath")"
echo $homedir # prints home path

দেখুন এই প্রশ্নের বিস্তারিত জানার জন্য

এছাড়াও, নোট করুন যে zsh এর অধীনে এটি যতটা সহজ হবে echo ${~dangerous_path}


echo ${~root}আমাকে zsh এ কোনও আউটপুট দেবেন না (ম্যাক ওএস এক্স)
অরওলোফিল

export test="~root/a b"; echo ${~test}
গিসকোস

9

এটি সম্পর্কে:

path=`realpath "$1"`

বা:

path=`readlink -f "$1"`

দেখতে দুর্দান্ত লাগছে, কিন্তু আমার ম্যাকের উপর রিয়েলপ্যাট নেই। এবং আপনাকে পথ লিখতে হবে = $ (রিয়েলপথ "$ 1")
হুগো

হাই @ হুগো আপনি আপনার নিজের কম্পাইল করতে পারেন realpathসি জন্য ইনস্ট্যান্সের মধ্যে কমান্ড, আপনি একটি এক্সিকিউটেবল তৈরি করতে পারেন realpath.exeব্যবহার ব্যাশ এবং জিসিসি এই কমান্ড লাইন থেকে: gcc -o realpath.exe -x c - <<< $'#include <stdlib.h> \n int main(int c,char**v){char p[9999]; realpath(v[1],p); puts(p);}'। চিয়ার্স
অলিবার

@ কিউক্সপ্লাসোন ঠিক নয়, কমপক্ষে লিনাক্সে: realpath ~->/home/myhome
ব্লুফাস্ট

iv'e Mac এ চোলাই সঙ্গে এটি ব্যবহার
nhed

1
@ ড্যাংগনফাস্ট আপনি টিল্ডকে কোটে সেট করে দিলে এটি কাজ করবে না, ফলাফল <workingdir>/~
মার্ফি

7

বিরিরি এবং হ্যালোলিওর উত্তরগুলিতে (কোনও পাং উদ্দেশ্যপ্রণোদিত) প্রসারিত করা: সাধারণ পদ্ধতিটি ব্যবহার করা হয় evalতবে এটি >ভেরিয়েবলের কিছু গুরুত্বপূর্ণ ক্যাভ্যাট, স্পেস এবং আউটপুট পুনঃনির্দেশ ( ) সহ আসে । নিম্নলিখিতটি আমার পক্ষে কাজ করে বলে মনে হচ্ছে:

mypath="$1"

if [ -e "`eval echo ${mypath//>}`" ]; then
    echo "FOUND $mypath"
else
    echo "$mypath NOT FOUND"
fi

নিম্নলিখিত প্রতিটি যুক্তি দিয়ে এটি ব্যবহার করে দেখুন:

'~'
'~/existing_file'
'~/existing file with spaces'
'~/nonexistant_file'
'~/nonexistant file with spaces'
'~/string containing > redirection'
'~/string containing > redirection > again and >> again'

ব্যাখ্যা

  • ${mypath//>}আউট রেখাচিত্রমালা >অক্ষর সময় একটি ফাইল পরাস্ত পারে eval
  • eval echo ...কি প্রকৃত টিল্ড সম্প্রসারণ নেই
  • -eআর্গুমেন্টের চারপাশে ডাবল-কোটগুলি স্পেস সহ ফাইলের নামের জন্য।

সম্ভবত আরও মার্জিত সমাধান আছে, তবে এটিই আমি সামনে আসতে পেরেছিলাম।


3
নামগুলি সম্বলিত আচরণের দিকে তাকিয়ে আপনি বিবেচনা করতে পারেন $(rm -rf .)
চার্লস ডাফি

1
>যদিও এই পাথগুলিতে আসলে অক্ষর রয়েছে তার বিরতি নেই?
রেডন রোসবারো

2

আমি বিশ্বাস করি এটিই আপনি খুঁজছেন

magic() { # returns unexpanded tilde express on invalid user
    local _safe_path; printf -v _safe_path "%q" "$1"
    eval "ln -sf ${_safe_path#\\} /tmp/realpath.$$"
    readlink /tmp/realpath.$$
    rm -f /tmp/realpath.$$
}

ব্যবহারের উদাহরণ:

$ magic ~nobody/would/look/here
/var/empty/would/look/here

$ magic ~invalid/this/will/not/expand
~invalid/this/will/not/expand

আমি আশ্চর্য হয়েছি যে নেতৃত্বের টিल्डগুলি এড়াতে printf %q পারে না - এটি একটি বাগ হিসাবে ফাইল করা প্রায় লোভনীয়, কারণ এটি এমন একটি পরিস্থিতিতে যেখানে এটি তার বর্ণিত উদ্দেশ্যে ব্যর্থ হয়। তবে অন্তর্বর্তী সময়ে, একটি ভাল কল!
চার্লস ডাফি

1
প্রকৃতপক্ষে - এই বাগটি 3.2.57 এবং 4.3.18 এর মধ্যে কোনও সময়ে স্থির হয়েছে, সুতরাং এই কোডটি আর কাজ করে না।
চার্লস ডাফি

1
ভালো কথা, আমি নেতৃস্থানীয় অপসারণের জন্য কোডের সাথে সামঞ্জস্য করেছি \ যদি এটি বিদ্যমান থাকে, তবে সমস্ত স্থির এবং কাজ করা হয়েছে: আমি যুক্তিগুলির উদ্ধৃতি না দিয়ে পরীক্ষা করছিলাম, সুতরাং এটি ফাংশনটি কল করার আগে এটি প্রসারিত হয়েছিল।
ওড়ওলোফিল

1

এখানে আমার সমাধান:

#!/bin/bash


expandTilde()
{
    local tilde_re='^(~[A-Za-z0-9_.-]*)(.*)'
    local path="$*"
    local pathSuffix=

    if [[ $path =~ $tilde_re ]]
    then
        # only use eval on the ~username portion !
        path=$(eval echo ${BASH_REMATCH[1]})
        pathSuffix=${BASH_REMATCH[2]}
    fi

    echo "${path}${pathSuffix}"
}



result=$(expandTilde "$1")

echo "Result = $result"

এছাড়াও, নির্ভর করার echoঅর্থ expandTilde -nপ্রত্যাশার মতো আচরণ করবে না এবং ব্যাকস্ল্যাশযুক্ত ফাইলের নামগুলি POSIX দ্বারা সংজ্ঞায়িত। Pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
চার্লস ডাফি

ভালো বল ধরা. আমি সাধারণত একটি ওয়ান-ইউজার মেশিন ব্যবহার করি তাই আমি কেসটি হ্যান্ডেল করার কথা ভাবিনি। তবে আমি মনে করি যে অন্য ব্যবহারকারীর জন্য / ইত্যাদি / পাসডাব্লুডি ফাইলের মাধ্যমে গ্রেপিং করে এই অন্যান্য কেসটি পরিচালনা করার জন্য ফাংশনটি সহজেই বাড়ানো যেতে পারে। আমি এটি অন্য কারও জন্য অনুশীলন হিসাবে ছেড়ে দেব :)।
জিনো

আপনি ইতিমধ্যে জটিল বলে মনে করেছেন এমন একটি উত্তরে আমি ইতিমধ্যে সেই অনুশীলনটি করেছি (এবং ওলডিপিডাব্লুডি কেস এবং অন্যান্যদের পরিচালনা করেছি)। :)
চার্লস ডাফি

প্রকৃতপক্ষে, আমি সবেমাত্র একটি সহজ সরল এক-লাইন সমাধান পেয়েছি যা অন্য ব্যবহারকারীর কেস পরিচালনা করতে হবে: পথ = e (ইকো cho orgPath)
জিনো

1
এফওয়াইআই: আমি কেবলমাত্র আমার সমাধানটি আপডেট করেছি যাতে এটি এখন ~ ব্যবহারকারী নামটি সঠিকভাবে পরিচালনা করতে পারে। এবং এটিও মোটামুটি নিরাপদ হওয়া উচিত। এমনকি যদি আপনি কোনও '/ tmp / $ (rm -rf / *)' যুক্তি হিসাবে রাখেন তবে এটি এটিকে নিখুঁতভাবে পরিচালনা করা উচিত।
জিনো

1

কেবল evalসঠিকভাবে ব্যবহার করুন : বৈধতা সহ।

case $1${1%%/*} in
([!~]*|"$1"?*[!-+_.[:alnum:]]*|"") ! :;;
(*/*)  set "${1%%/*}" "${1#*/}"       ;;
(*)    set "$1" 
esac&& eval "printf '%s\n' $1${2+/\"\$2\"}"

এটি সম্ভবত নিরাপদ - এটি ব্যর্থ হওয়ার মতো কোনও মামলা আমি খুঁজে পাইনি। এটি বলেছিল, যদি আমরা ইওল "সঠিকভাবে" ব্যবহার করতে গিয়ে কথা বলতে চাই, তবে আমি যুক্তি দেব যে অরওলোফিলের উত্তরটি আরও ভাল অনুশীলনকে অনুসরণ করে: আমি printf %qহাতের লিখিত বৈধতা কোডের কোনও বাগ নেই বলে বিশ্বাস করার চেয়ে শেলটি নিরাপদে জিনিস থেকে বাঁচতে বিশ্বাস করি I ।
চার্লস ডাফি

@ চার্লস ডফি - এটি নির্বোধ। শেলের একটি% q নাও থাকতে পারে - এবং printfএটি একটি $PATH'd কমান্ড'।
মাইক্রোসার্ভ

1
এই প্রশ্নটি ট্যাগ করা হয় না bash? যদি তা হয় তবে এটি printfঅন্তর্নির্মিত এবং %qএটি উপস্থিত থাকার গ্যারান্টিযুক্ত।
চার্লস ডাফি

@ চার্লস ডাফি - কোন সংস্করণ?
মাইক্রজারভ

1
@ চার্লস ডাফি - এটি ... বেশ তাড়াতাড়ি। তবে আমি এখনও এটি অদ্ভুত মনে করি যে আপনি আপনার চোখের সামনে কোড করার চেয়ে একটি% কিউআর্গকে বেশি বিশ্বাস করতে পারবেন, এটি বিশ্বাস না করার bashজন্য আগে যথেষ্ট পরিমাণে ব্যবহৃত হয়েছিল ive চেষ্টা করুন:x=$(printf \\1); [ -n "$x" ] || echo but its not null!
মাইক্রোজার

1

হোকন হাগল্যান্ডের বাশ উত্তরের সমতুল্য পসিক্স ফাংশন এখানে

expand_tilde() {
    tilde_less="${1#\~/}"
    [ "$1" != "$tilde_less" ] && tilde_less="$HOME/$tilde_less"
    printf '%s' "$tilde_less"
}

2017-12-10 সম্পাদনা করুন: '%s'মন্তব্যগুলিতে @ চার্লসডুফি যোগ করুন ।


1
printf '%s\n' "$tilde_less"সম্ভবত? অন্যথায় ফাইলের নামটি প্রসারিত করাতে ব্যাকস্ল্যাশ %s, বা অন্য সিনট্যাক্স অর্থপূর্ণ থাকলে এটি খারাপ ব্যবহার করবে printf। এগুলি ব্যতীত, যদিও এটি দুর্দান্ত উত্তর - সঠিক (যখন বাশ / কেএস এক্সটেনশানগুলি কভার করার দরকার নেই), অবশ্যই নিরাপদ (কোনও শোক প্রকাশ করবেন না eval) এবং সংশ্লেষ।
চার্লস ডাফি 21

1

কেন সরাসরি অভিপ্রায় ব্যবহারকারীর হোম ডিরেক্টরি পেতে আগ্রহী না?

$ getent passwd mike | cut -d: -f6
/users/mike

0

কেবল ফাঁকা জায়গাগুলির জন্য বিরিরির উত্তর প্রসারিত করার জন্য: আপনি evalকমান্ডটি ব্যবহার করতে পারবেন না কারণ এটি ফাঁক দিয়ে মূল্যায়ন আলাদা করে দেয়। একটি সমাধান হ'ল স্পষ্ট স্থানগুলিকে অস্থায়ীভাবে ইভাল কমান্ডের জন্য প্রতিস্থাপন করা:

mypath="~/a/b/c/Something With Spaces"
expandedpath=${mypath// /_spc_}    # replace spaces 
eval expandedpath=${expandedpath}  # put spaces back
expandedpath=${expandedpath//_spc_/ }
echo "$expandedpath"    # prints e.g. /Users/fred/a/b/c/Something With Spaces"
ls -lt "$expandedpath"  # outputs dir content

এই উদাহরণটি অবশ্যই এই ধারনাটির উপর নির্ভর করে যা mypathকখনও চর ক্রম ধারণ করে না "_spc_"


1
ট্যাব, বা নিউলাইনস, বা আইএফএস-এ অন্য কিছুর সাথে কাজ করে না ... এবং মেটাচার্যাক্টারের আশেপাশের সুরক্ষা সরবরাহ করে না এমন পাথগুলি রয়েছে$(rm -rf .)
চার্লস ডাফি

0

পাইথনে এটি করা সহজ হতে পারে।

(1) ইউনিক্স কমান্ড লাইন থেকে:

python -c 'import os; import sys; print os.path.expanduser(sys.argv[1])' ~/fred

ফলাফল স্বরূপ:

/Users/someone/fred

(২) ব্যাশ স্ক্রিপ্টের মধ্যে ওয়ান-অফ হিসাবে - এটি সংরক্ষণ করুন test.sh:

#!/usr/bin/env bash

thepath=$(python -c 'import os; import sys; print os.path.expanduser(sys.argv[1])' $1)

echo $thepath

চলমান bash ./test.shফলাফল:

/Users/someone/fred

(3) ইউটিলিটি হিসাবে - expanduserচালানোর অনুমতি নিয়ে আপনার পথে যে কোনও জায়গায় এটি সংরক্ষণ করুন:

#!/usr/bin/env python

import sys
import os

print os.path.expanduser(sys.argv[1])

এটি কমান্ড লাইনে ব্যবহার করা যেতে পারে:

expanduser ~/fred

বা স্ক্রিপ্টে:

#!/usr/bin/env bash

thepath=$(expanduser $1)

echo $thepath

বা পাইথনের কাছে কেবল '~' পাশ করে "/ হোম / ফ্রেড" ফিরবেন কীভাবে?
টম রাসেল

1
মোয়ার উদ্ধৃতি দরকার। echo $thepathবগি; করা প্রয়োজন echo "$thepath", অথবা; (globs তাদের সম্প্রসারিত হচ্ছে সঙ্গে নাম ট্যাব বা স্পেস রান নাম একক স্পেস রূপান্তরিত হচ্ছে) কম-বিরল ক্ষেত্রেই ঠিক করতে printf '%s\n' "$thepath"। একটি ফাইল নামে খুব বিরল বেশী ঠিক করতে (অর্থাত -n, বা সহ একটি ফাইল এক্সএসআই-কমপ্লায়েন্ট সিস্টেমে ব্যাকস্ল্যাশ লিটারাল)। একইভাবে,thepath=$(expanduser "$1")
চার্লস ডাফি

... ব্যাকস্ল্যাশ লিটারাল বলতে কী বোঝাতে চাইছিলাম তা বোঝার জন্য, pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html দেখুন - echoকোনও যুক্তিতে ব্যাকস্ল্যাশ থাকলে পসিক্স সম্পূর্ণ বাস্তবায়ন-সংজ্ঞায়িত পদ্ধতিতে আচরণ করতে দেয় ; POSIX হুকুম ডিফল্টে ঐচ্ছিক XSI এক্সটেনশন (কোন -eবা -Eপ্রয়োজন) যেমন নামের জন্য সম্প্রসারণ আচরণে।
চার্লস ডাফি

0

সর্বাধিক : 'ম্যাজিক' প্রতিস্থাপন করুন 'ইওল প্রতিধ্বনি' দিয়ে।

$ eval echo "~"
/whatever/the/f/the/home/directory/is

সমস্যা: আপনি অন্যান্য ভেরিয়েবলগুলির সাথে ইস্যুগুলিতে চলে যাবেন কারণ evilভালটি খারাপ। এই ক্ষেত্রে:

$ # home is /Users/Hacker$(s)
$ s="echo SCARY COMMAND"
$ eval echo $(eval echo "~")
/Users/HackerSCARY COMMAND

নোট করুন যে ইঞ্জেকশনটির সমস্যাটি প্রথম প্রসারণে ঘটে না। সুতরাং আপনি যদি কেবল এটির magicসাথে প্রতিস্থাপন করেন তবে আপনার eval echoঠিক আছে। তবে যদি আপনি করেনecho $(eval echo ~) তা করেন তবে তা ইনজেকশনের পক্ষে সংবেদনশীল।

একইভাবে, আপনি যদি এর eval echo ~পরিবর্তে eval echo "~"এটি করেন তবে এটি দ্বিগুণ প্রসারিত গণনা করবে এবং তাই এখনই ইনজেকশন সম্ভব হবে।


1
আপনি যা বলেছেন তার বিপরীতে, এই কোডটি অনিরাপদ । উদাহরণস্বরূপ, পরীক্ষা s='echo; EVIL_COMMAND'। (এটা কারণ ব্যর্থ হবে EVIL_COMMANDআপনার কম্পিউটারের তে অস্তিত্ব নেই কিন্তু যদি যে কমান্ড ছিলেন। rm -r ~উদাহরণস্বরূপ, এটি আপনার হোম ডিরেক্টরীতে মোছা হবে।)
কনরাড রুডলফ

0

আমি রিড-ই ব্যবহার করে (অন্যদের মধ্যে) ব্যবহার করে পাঠের পরে পরিবর্তনশীল প্যারামিটার বিকল্পের সাথে এটি করেছি। সুতরাং ব্যবহারকারী পাথটি ট্যাব-সম্পূর্ণ করতে পারে এবং যদি ব্যবহারকারী কোনও ~ পথে প্রবেশ করে তবে তা বাছাই হয়।

read -rep "Enter a path:  " -i "${testpath}" testpath 
testpath="${testpath/#~/${HOME}}" 
ls -al "${testpath}" 

সংযুক্ত সুবিধাটি হ'ল যদি টিলড না থাকে তবে ভেরিয়েবলের কিছুই হয় না, এবং যদি একটি টিলড থাকে তবে প্রথম অবস্থানে না থাকে তবে এটিকেও উপেক্ষা করা হবে।

(আমি এটি পড়ার জন্য অন্তর্ভুক্ত করি যেহেতু আমি এটি লুপে ব্যবহার করি যাতে কোনও সমস্যা হলে ব্যবহারকারী পথটি ঠিক করতে পারে))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.