কোনও ভেরিয়েবলের মান হারাতে না পারলে আমি কীভাবে রফতানি করতে পারি?


10

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

foo=bar
export foo

এখন, আমি এটি আন-এক্সপোর্ট করতে চাই। এটি বলার অপেক্ষা রাখে না, যদি আমি করি তবে sh -c 'echo "$foo"'আমার পাওয়া উচিত ছিল না bar। একেবারে পরিবেশে fooদেখা উচিত নয় sh -csh -cকেবল একটি উদাহরণ, ভেরিয়েবলের উপস্থিতি দেখানোর একটি সহজ উপায়। কমান্ডটি যে কোনও কিছু হতে পারে - এটি এমন কিছু হতে পারে যার পরিবেশে ভেরিয়েবলের উপস্থিতি দ্বারা এর আচরণটি প্রভাবিত হয়।

আমি পারি:

  1. unset পরিবর্তনশীল, এবং এটি হারাতে
  2. envপ্রতিটি কমান্ডের জন্য এটি ব্যবহার করে সরান :env -u foo sh -c 'echo "$foo"'
    • আপনি যদি কিছুক্ষণের জন্য বর্তমান শেলটি ব্যবহার চালিয়ে যেতে চান তবে অবাস্তব।

আদর্শভাবে, আমি ভেরিয়েবলের মান রাখতে চাই, তবে এটি একটি শিশু প্রক্রিয়াতে মোটেও প্রদর্শন করা উচিত নয়, এমনকি খালি ভেরিয়েবল হিসাবেও নয়।

আমার ধারণা আমি করতে পারি:

otherfoo="$foo"; unset foo; foo="$otherfoo"; unset otherfoo

otherfooএটি ইতিমধ্যে যদি বিদ্যমান থাকে তবে এটি ঝুঁকিপূর্ণ ।

যে একমাত্র উপায়? কোন মানক উপায় আছে?


1
আপনি যথেষ্ট পরিমাণে পোর্টেবল mktempহলে এটি ব্যবহার করে অস্থায়ী ফাইলে মানটি প্রতিধ্বনিত করতে পারেন এবং মানটি আনসেট করতে পারেন এবং ভেরিয়েবলটি নির্ধারণের জন্য অস্থায়ী ফাইলটি উত্স করতে পারেন। কমপক্ষে একটি অস্থায়ী ফাইল শেল ভেরিয়েবলের বিপরীতে আরও বেশি কম নির্বিচারে নাম তৈরি করা যেতে পারে।
টমাস ডিকি

@ সুকিমিন্দার sh -cআদেশটি কেবল একটি উদাহরণ। আপনি যদি চান তবে কোনও কমান্ড নিন যার মধ্যে আপনি কোনও পরিবর্তনশীলকে স্থিতিশীল করতে পারবেন না যদি তা করতে পারেন।
মুড়ু

উত্তর:


6

কোনও মানক উপায় নেই।

আপনি একটি ফাংশন ব্যবহার করে একটি অস্থায়ী পরিবর্তনশীল ব্যবহার এড়াতে পারবেন। নিম্নলিখিত ফাংশনটি আনসেট ভেরিয়েবলগুলি সেট না করা এবং খালি ভেরিয়েবলগুলি খালি রাখার যত্ন নেয়। এটি কিছু শেল যেমন কেবল পঠনযোগ্য বা টাইপযুক্ত ভেরিয়েবলগুলিতে পাওয়া বৈশিষ্ট্যগুলিকে সমর্থন করে না।

unexport () {
  while [ "$#" -ne 0 ]; do
    eval "set -- \"\${$1}\" \"\${$1+set}\" \"\$@\""
    if [ -n "$2" ]; then
      unset "$3"
      eval "$3=\$1"
    fi
    shift; shift; shift
  done
}
unexport foo bar

Ksh, bash এবং zsh এ আপনি এর সাথে একটি ভেরিয়েবল আনক্সপোর্ট করতে পারবেন typeset +x foo। এটি প্রকারের মতো বিশেষ বৈশিষ্ট্য সংরক্ষণ করে তাই এটি ব্যবহার করা ভাল pre আমি মনে করি যে সমস্ত শেল একটি typesetবিল্টিন আছে typeset +x

case $(LC_ALL=C type typeset 2>&1) in
  typeset\ *\ builtin) unexport () { typeset +x -- "$@"; };;
  *) unexport () {  };; # code above
esac

1
যাদের সাথে অপরিচিত তাদের জন্য ${var+foo}এটি সেট করা আছে fooকিনা তা মূল্যায়ন করে var, এমনকি খালি হলেও এবং অন্যথায় কিছুই নয়।
মুড়ু

বলুন, পূর্বেরটিকে সমর্থনকারী শেলগুলির জন্য typeset +xবনাম সম্পর্কে আপনার কোনও মন্তব্য আছে export -n? কি export -nদুর্লভ, অথবা এটি কিছু বৈশিষ্ট্য সংরক্ষণ করে না?
মুড়ু

@ মুরু আপনি যদি বাশ স্ক্রিপ্ট লিখছেন তবে আপনি ব্যবহার করতে পারেন export -nবা typeset +xউদাসীনভাবে। Ksh বা zsh এ কেবল আছে typeset +x
গিলস 7'6

7

সম্পাদনা করুন: জন্য bashশুধুমাত্র, যেমন মন্তব্য নির্দিষ্ট:

-nবিকল্প exportঅপসারণ exportপ্রতিটি প্রদত্ত নাম থেকে সম্পত্তি। (দেখুন help export।)

সুতরাং জন্য bash, কমান্ড আপনাকে চাই:export -n foo


1
এটি শেল-নির্দিষ্ট ( POSIX দেখুন ), ওপি শেল নির্দিষ্ট করে না, তবে সমস্যা সমাধানের একটি মানক উপায় চেয়েছিল ।
টমাস ডিকি

1
@ থমাসডিকি, এটি সম্পর্কে অবগত ছিল না। ধন্যবাদ, আপডেট হয়েছে।
ওয়াইল্ডকার্ড

3

আমি অনুরূপ একটি পসিক্স ফাংশন লিখেছি, তবে এটি স্বেচ্ছাসেবীর কোড কার্যকর করার ঝুঁকিপূর্ণ নয়:

unexport()
    while case ${1##[0-9]*} in                   ### rule out leading numerics
          (*[!_[:alnum:]]*|"")                   ### filter out bad|empty names
          set "" ${1+"bad name: '$1'"}           ### prep bad name error
          return ${2+${1:?"$2"}}                 ### fail w/ above err or return 
          esac
    do    eval  set '"$'"{$1+$1}"'" "$'"$1"'" "$'@\" ###  $1 = (  $1+ ? $1 : "" )
          eval  "${1:+unset $1;$1=\$2;} shift 3"     ### $$1 = ( $1:+ ? $2 : -- )
    done

এটি যতটা আর্গুমেন্ট সরবরাহ করতে পারে তত পরিচালনা করে। যদি কোনও যুক্তি যদি একটি বৈধ নাম হয় যা অন্যথায় ইতিমধ্যে সেট করা থাকে না তবে তা নিঃশব্দে উপেক্ষা করা হয়। যদি কোনও যুক্তি একটি খারাপ নাম হয় তবে এটি স্টাডারকে লিখতে এবং যথাযথভাবে থামায়, যদিও তার কমান্ড-লাইনে কোনও অবৈধের আগে কোনও বৈধ নাম এখনও প্রক্রিয়া করা হবে।

আমি অন্য উপায় চিন্তা। আমি এটি অনেক ভাল পছন্দ করি।

unexport()
        while   unset OPTARG; OPTIND=1           ### always work w/ $1
                case  ${1##[0-9]*}    in         ### same old same old
                (*[!_[:alnum:]]*|"")             ### goodname && $# > 0 || break
                    ${1+"getopts"} : "$1"        ### $# ? getopts : ":"
                    return                       ### getopts errored or ":" didnt
                esac
        do      eval   getopts :s: '"$1" -"${'"$1+s}-\$$1\""
                eval   unset  "$1;  ${OPTARG+$1=\${OPTARG}#-}"
                shift
        done

ঠিক আছে, এই দু'জনেই একই কৌশল ব্যবহার করে। মূলত যদি শেল ভার সেট না করে থাকে তবে এটির সাথে একটি রেফারেন্স কোনও +প্যারামিটার বিস্তারের সাথে প্রসারিত হবে না । তবে যদি সেট করা থাকে - এর মান নির্বিশেষে - একটি প্যারামিটার বিস্তৃতি: যেমন ${parameter+word}প্রসারিত হবে word- এবং ভেরিয়েবলের মান নয়। এবং সুতরাং শেল ভেরিয়েবলগুলি স্ব-পরীক্ষা এবং সাফল্যের স্ব-বিকল্প।

তারা স্ব-ব্যর্থও হতে পারে । শীর্ষের ফাংশনে যদি কোনও খারাপ নাম পাওয়া যায় তবে আমি স্থানান্তরিত $1হয়ে নাল $2ছেড়ে চলে যাই $1কারণ পরবর্তী কাজটি আমি করি returnসফল হয় যদি সমস্ত আরগগুলি প্রক্রিয়াজাত করা হয় এবং লুপটি শেষ হয়, বা, আরগটি অবৈধ থাকলে শেলটি হবে প্রসারিত $2মধ্যে $1:?যা স্ক্রিপ্টের শেল হত্যা এবং যখন লেখা একটি ইন্টারেক্টিভ এক একটি ইন্টারাপ্ট ফিরে আসবে wordstderr হবে।

দ্বিতীয়টিতে getoptsঅ্যাসাইনমেন্ট রয়েছে। এবং এটি কোনও খারাপ নাম বরাদ্দ করবে না - বরং এটি লিখুন এটি স্ট্যাডারকে একটি স্ট্যান্ডার্ড ত্রুটি বার্তা লিখবে। যুক্তিটি $OPTARG যদি প্রথম স্থানে একটি সেট ভেরিয়েবলের নাম হয় তবে এটি আরগের মান সংরক্ষণ করে । সুতরাং getoptsপ্রয়োজনীয় সমস্ত কাজ করার পরে evalএকটি সেটকে OPTARGযথাযথ কার্যভারে প্রসারিত করা।


2
এই দিনগুলির মধ্যে একটি, আমি আপনার উত্তরগুলির মধ্যে একটিতে আমার মাথা গুটিয়ে দেওয়ার চেষ্টা করার পরে আমি কোথাও মনোরোগের ওয়ার্ডে থাকব। : D অন্য উত্তর কীভাবে নির্বিচারে কোড প্রয়োগে ভোগে? আপনি একটি উদাহরণ প্রদান করতে পারেন?
মুড়ু

3
@ মুরু - যুক্তি একটি অবৈধ নাম না হলে নয়। তবে সমস্যাটি নয় - সমস্যাটি হ'ল ইনপুটটি বৈধ নয়। হ্যাঁ, এটি স্বেচ্ছাসেবক কোড কার্যকর করার জন্য আপনি এটি একটি অদ্ভুত নাম দিয়ে যুক্তিটি পাস করার প্রয়োজন হয় - তবে এটি ইতিহাসের প্রতিটি সিভিইর পক্ষে অনেক বেশি ভিত্তি। যদি আপনি exportকোনও অদ্ভুত নাম চেষ্টা করেন তবে এটি আপনার কম্পিউটারকে হত্যা করবে না।
মাইক্রজারভ

1
@ মুরু - ওহ, এবং যুক্তিগুলি নির্বিচারে হতে পারে: var=something; varname=var; export "$varname"পুরোপুরি বৈধ। একই জন্য যায় unset, এবং এই এবং অন্যটির সাথে, তবে সেই "$varname"পরিবর্তনশীলটির বিষয়বস্তুটি যে মুহুর্তে পাগল হয়, তা আফসোসযোগ্য হতে পারে। এবং এটি পুরোপুরি পুরো bashফাংশন রফতানি পরাজয় যেভাবেই ঘটেছিল pretty
মাইক্রজারভ 4

1
@ মিকসার্ভ আমি মনে করি আপনি যদি সেই অপ্রচলিত কোডটি নিজেকে ব্যাখ্যা করে এমন কোডের সাথে প্রতিস্থাপন করেন (বা কমপক্ষে লাইনে মন্তব্য করেছেন)
PSkocik

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