আপনি যদি মৃত্যুদন্ড কার্যকর করার সময় কোনও স্ক্রিপ্ট সম্পাদনা করেন?


31

আমার একটি সাধারণ প্রশ্ন রয়েছে, যা লিনাক্সে প্রক্রিয়াগুলি কীভাবে পরিচালনা করা হয় তা ভুল বোঝাবুঝির ফলে হতে পারে।

আমার উদ্দেশ্যগুলির জন্য আমি একটি 'স্ক্রিপ্ট' সংজ্ঞায়িত করতে যাচ্ছি বর্তমান ব্যাবহারকারীর জন্য সক্ষম করা কার্যকর করার অনুমতি সহ একটি পাঠ্য ফাইলে বাশ কোডের স্নিপেট সংরক্ষণ করা।

আমার কাছে একের পর এক স্ক্রিপ্ট রয়েছে যা একে অপরকে ডাকে। সরলতার জন্য আমি এগুলিকে এ, বি এবং সি স্ক্রিপ্ট বলব, স্ক্রিপ্ট এ ধারাবাহিক বিবৃতি বহন করে এবং বিরতি দেয়, এটি স্ক্রিপ্ট বি কার্যকর করে, তারপর এটি বিরতি দেয়, তারপরে এটি স্ক্রিপ্ট সি সম্পাদন করে অন্য কথায়, সিরিজটি series পদক্ষেপের কিছু এইরকম:

স্ক্রিপ্ট রান করুন:

  1. বিবৃতি ধারাবাহিক
  2. বিরতি
  3. স্ক্রিপ্ট চালান বি
  4. বিরতি
  5. স্ক্রিপ্ট রান করুন

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

এখানে আসল প্রশ্নটি এখানে রয়েছে, এটি চলমান অবস্থায় স্ক্রিপ্ট এ সম্পাদনার কোনও উপায় আছে কি? বা সম্পাদনাটি কার্যকর হওয়ার পরে কি অসম্ভব?


2
আমি মনে করি এটি শেলের উপর নির্ভর করে। যদিও আপনি উল্লেখ করেছেন যে আপনি ব্যাশ ব্যবহার করছেন। মনে হচ্ছে এটি শেল স্ক্রিপ্টগুলি অভ্যন্তরীণভাবে বোঝায় যেভাবে তার উপর নির্ভরশীল।
strugee

আপনি যদি ফাইলটি চালনার পরিবর্তে উত্সটি সরবরাহ করেন তবে আচরণেও পরিবর্তন হতে পারে।
strugee

1
আমি মনে করি চালানোর আগে বাশ একটি সম্পূর্ণ স্ক্রিপ্ট স্মৃতিতে পড়ে।
w4etwetewtwet

2
@ হ্যান্ডুয়েল, না এটি হয় না। আপনি প্রবেশ করা আদেশগুলি ব্যাখ্যা করতে প্রম্পটে "প্রস্থান" টাইপ না করা অপেক্ষা এটি পছন্দ করে না।
স্টাফেন চেজেলাস

1
@ স্টাফেনচাজলাস হ্যাঁ টার্মিনাল থেকে পড়ছেন এটি স্ক্রিপ্ট চালানোর চেয়ে আলাদা নয় different
w4etwetewtwet

উত্তর:


21

ইউনিক্সে, বেশিরভাগ সম্পাদক সম্পাদিত সামগ্রীগুলি সহ একটি নতুন অস্থায়ী ফাইল তৈরি করে কাজ করেন। সম্পাদিত ফাইলটি সংরক্ষণ করা হলে, আসল ফাইলটি মুছে ফেলা হয় এবং অস্থায়ী ফাইলটির নামটি মূল নামকরণ করা হয়। (অবশ্যই ড্যাটালাস রোধে বিভিন্ন সুরক্ষার ব্যবস্থা রয়েছে)) এটি উদাহরণস্বরূপ, (" ইনস -প্লেস") পতাকার সাথে ব্যবহৃত sedবা perlযখন ব্যবহৃত হয়েছিল সেই শৈলী -i, যা আসলে "স্থান" নয়। এটিকে "পুরানো নাম সহ নতুন জায়গা" বলা উচিত ছিল।

এটি ভালভাবে কাজ করে কারণ ইউনিক্স আশ্বাস দেয় (কমপক্ষে স্থানীয় ফাইল সিস্টেমগুলির জন্য) যে একটি খোলা ফাইল বন্ধ না হওয়া অবধি বিদ্যমান থাকবে, এমনকি যদি এটি "মুছে ফেলা" হয় এবং একই নামের নতুন ফাইল তৈরি না হয়। (এটি কাকতালীয় নয় যে ইউনিক্স সিস্টেম কোনও ফাইলকে "মুছে ফেলতে" ডাকে আসলে "আনলিঙ্ক" বলে) শেলটি এমনকি মূল ফাইলটি খোলার পরেও পরিবর্তনগুলি দেখতে পাবে না।

[দ্রষ্টব্য: সমস্ত মান-ভিত্তিক মন্তব্যগুলির মতো, উপরেরটি একাধিক ব্যাখ্যার সাপেক্ষে এবং এনএফএসের মতো বিভিন্ন কোণার-কেস রয়েছে। শিশুরা ব্যতিক্রমগুলি দিয়ে মন্তব্যগুলি পূরণ করতে স্বাগত]

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

সুতরাং, যদি আপনি কোনও শেল দ্বারা প্রক্রিয়া করার সময় কোনও ফাইল সম্পাদনা করতে চান তবে আপনার কাছে দুটি বিকল্প রয়েছে:

  1. আপনি ফাইলটিতে সংযোজন করতে পারেন। এটি সর্বদা কাজ করা উচিত।

  2. আপনি ঠিক একই দৈর্ঘ্যের নতুন সামগ্রীগুলি দিয়ে ফাইলটি ওভাররাইট করতে পারেন । শেলটি ইতিমধ্যে ফাইলটির সেই অংশটি পড়েছে কি না তার উপর নির্ভর করে এটি কাজ করতে পারে না not যেহেতু বেশিরভাগ ফাইল আই / ও-তে পড়া বাফারদের অন্তর্ভুক্ত রয়েছে এবং যেহেতু আমি জানি সমস্ত শেলগুলি এটি কার্যকর করার আগে একটি সম্পূর্ণ যৌগিক কমান্ড পড়ে, তাই আপনি এটি থেকে দূরে সরে যাবেন এটির সম্ভাবনা খুব কম। এটি অবশ্যই নির্ভরযোগ্য হবে না।

আমি পসিক্স স্ট্যান্ডার্ডের এমন কোনও শব্দের কথা জানি না যার ফাইলটি সম্পাদন করার সময় আসলে স্ক্রিপ্ট ফাইলটিতে সংযুক্ত হওয়ার সম্ভাবনা প্রয়োজন, সুতরাং এটি প্রতিটি পিক্সিক্স কমপ্লায়েন্ট শেলটির সাথে কাজ করতে পারে না, প্রায় বর্তমানের অফারটির সাথে কম- এবং কখনও কখনও-পিক্সিক-অনুগত শেল। তাই ওয়াইএমএমভি। তবে যতদূর আমি জানি, এটি ব্যাশের সাথে নির্ভরযোগ্যভাবে কাজ করে।

প্রমাণ হিসাবে, এখানে বাশ-এর ​​কুখ্যাত 99 বোতল বিয়ার প্রোগ্রামের বাস্তবায়ন, যা ddওভাররাইট এবং সংযোজন করতে ব্যবহার করে (ওভাররাইটিং সম্ভবত নিরাপদ কারণ এটি বর্তমানে সম্পাদনকারী রেখাকে প্রতিস্থাপন করে, যা সর্বদা সর্বশেষের লাইন থাকে ফাইলটি ঠিক একই দৈর্ঘ্যের একটি মন্তব্য সহ; আমি এটি করেছি যাতে স্ব-পরিবর্তনকারী আচরণ ছাড়াই শেষ ফলাফলটি কার্যকর করা যায়))

#!/bin/bash
if [[ $1 == reset ]]; then
  printf "%s\n%-16s#\n" '####' 'next ${1:-99}' |
  dd if=/dev/stdin of=$0 seek=$(grep -bom1 ^#### $0 | cut -f1 -d:) bs=1 2>/dev/null
  exit
fi

step() {
  s=s
  one=one
  case $beer in
    2) beer=1; unset s;;
    1) beer="No more"; one=it;;
    "No more") beer=99; return 1;;
    *) ((--beer));;
  esac
}
next() {
  step ${beer:=$(($1+1))}
  refrain |
  dd if=/dev/stdin of=$0 seek=$(grep -bom1 ^next\  $0 | cut -f1 -d:) bs=1 conv=notrunc 2>/dev/null
}
refrain() {
  printf "%-17s\n" "# $beer bottles"
  echo echo ${beer:-No more} bottle$s of beer on the wall, ${beer:-No more} bottle$s of beer.
  if step; then
    echo echo Take $one down, pass it around, $beer bottle$s of beer on the wall.
    echo echo
    echo next abcdefghijkl
  else
    echo echo Go to the store, buy some more, $beer bottle$s of beer on the wall.
  fi
}
####
next ${1:-99}   #

আমি যখন এটি চালনা করি, এটি "আর নেই" দিয়ে শুরু হয়, তারপরে -1 এবং অনির্দিষ্টকালের জন্য নেতিবাচক সংখ্যায় চলে যায়।
ড্যানিয়েল হার্শকোভিচ

আমি যদি export beer=100স্ক্রিপ্টটি চালানোর আগে করি তবে এটি প্রত্যাশার মতো কাজ করে।
ড্যানিয়েল হার্শকোভিচ

@ ড্যানিয়েল হার্শকোভিচ: একেবারে ঠিক; আমার পক্ষ থেকে opালু পরীক্ষা। আমি মনে করি আমি এটি স্থির করেছি; এটি এখন একটি alচ্ছিক গণনা প্যারামিটার নেয়। যদি প্যারামিটারটি ক্যাশেড অনুলিপিটির সাথে সামঞ্জস্য না করে তবে একটি স্বয়ংক্রিয়ভাবে পুনরায় সেট করা একটি আরও ভাল এবং আকর্ষণীয় সমাধান fix
ধনী 16

18

bash কমান্ডগুলি কার্যকর করার পূর্বে এটি কমান্ডগুলি পঠন করে তা নিশ্চিত করতে অনেক দীর্ঘ যায়।

উদাহরণস্বরূপ:

cmd1
cmd2

শেলটি ব্লকগুলি দ্বারা স্ক্রিপ্টটি পড়বে, সুতরাং সম্ভবত উভয় কমান্ড পড়বে, প্রথমটির ব্যাখ্যা করবে এবং তারপরে cmd1স্ক্রিপ্টের শেষে ফিরে এসো এবং স্ক্রিপ্টটি আবার পড়তে cmd2এবং এটি সম্পাদন করতে পারে।

আপনি এটি সহজে যাচাই করতে পারেন:

$ cat a
echo foo | dd 2> /dev/null bs=1 seek=50 of=a
echo bar
$ bash a
foo

(যদিও এতে straceআউটপুটটি দেখছি , মনে হচ্ছে এটি কয়েক বছর আগে আমি একই চেষ্টা করার চেয়ে কিছু আরও অভিনব জিনিস (যেমন তথ্য কয়েকবার পড়ার জন্য, ফিরে অনুসন্ধান করার চেষ্টা করে ...) করে) সুতরাং পিছনে সন্ধানের বিষয়ে উপরের আমার বক্তব্যটি হতে পারে আরও নতুন সংস্করণে প্রয়োগ করবেন না)।

তবে আপনি যদি আপনার স্ক্রিপ্টটি লিখেন তবে:

{
  cmd1
  cmd2
  exit
}

শেলটি সমাপ্তি অবধি পড়তে হবে }, মেমরির মধ্যে সঞ্চয় করতে হবে এবং এটি সম্পাদন করতে হবে। এর কারণে exit, শেলটি আবার স্ক্রিপ্ট থেকে পঠিত হবে না যাতে শেলটি ব্যাখ্যা করার সময় আপনি নিরাপদে সম্পাদনা করতে পারবেন।

বিকল্পভাবে, স্ক্রিপ্ট সম্পাদনা করার সময়, আপনি স্ক্রিপ্টের একটি নতুন অনুলিপি লিখেছেন তা নিশ্চিত করুন। শেলটি আসলটি পড়তে থাকবে (এটি মুছে ফেলা বা পুনরায় নামকরণ করা হলেও)।

এটি করার জন্য, নাম পরিবর্তন the-scriptকরে এটিকে the-script.oldঅনুলিপি the-script.oldকরুন the-scriptএবং সম্পাদনা করুন।


4

স্ক্রিপ্টটি চলাকালীন পরিবর্তিত হওয়ার কোনও নিরাপদ উপায় নেই কারণ শেলটি ফাইল পড়তে বাফারিং ব্যবহার করতে পারে। এছাড়াও, যদি স্ক্রিপ্টটি কোনও নতুন ফাইলের পরিবর্তে এটি সংশোধন করা হয় তবে শেলগুলি সাধারণত কিছু নির্দিষ্ট ক্রিয়াকলাপ সম্পাদনের পরে কেবল নতুন ফাইলটি পড়বে।

প্রায়শই, সম্পাদনার সময় কোনও স্ক্রিপ্ট পরিবর্তন করা হয়, শেলটি সিনট্যাক্স ত্রুটিগুলি রিপোর্ট করে ends এটি এই সত্যের কারণে যে, যখন শেলটি স্ক্রিপ্ট ফাইলটি বন্ধ হয়ে যায় এবং পুনরায় খোলে, এটি ফিরতি পুনরায় প্রতিস্থাপনের জন্য ফাইলটিতে বাইট অফসেট ব্যবহার করে।


4

আপনি আপনার স্ক্রিপ্টে একটি ফাঁদ সেট করে এবং তারপরে execনতুন স্ক্রিপ্টের সামগ্রীগুলি বেছে নেওয়ার মাধ্যমে এটি পেতে পারেন। তবে নোট করুন, execকলটি স্ক্র্যাচ থেকে স্ক্রিপ্ট শুরু করে এবং এটি চলমান প্রক্রিয়াতে পৌঁছেছে সেখান থেকে নয়, এবং স্ক্রিপ্ট বি কল হবে (এগিয়ে যাবে)।

#! /bin/bash

CMD="$0"
ARGS=("$@")

trap reexec 1

reexec() {
    exec "$CMD" "${ARGS[@]}"
}

while : ; do sleep 1 ; clear ; date ; done

এটি স্ক্রিনে তারিখটি প্রদর্শন করতে থাকবে। আমি তখন আমার স্ক্রিপ্টটি সম্পাদনা করতে এবং এতে পরিবর্তন dateকরতে পারি echo "Date: $(date)"। লেখার পরে চলমান স্ক্রিপ্টটি এখনও কেবল তারিখটি প্রদর্শন করে। আমি trapক্যাপচারের জন্য যে সিগন্যালটি প্রেরণ করেছি তা যদি কখনই প্রেরণ করা হয় তবে স্ক্রিপ্টটি exec(চলমান চলমান প্রক্রিয়াটি নির্দিষ্ট কমান্ডের সাথে প্রতিস্থাপন করবে ) যা আদেশ $CMDএবং আর্গুমেন্ট $@। আপনি ইস্যু করে এটি করতে পারেন kill -1 PID- যেখানে পিআইডি হ'ল চলমান স্ক্রিপ্টের পিআইডি - এবং কমান্ড আউটপুটটির Date:আগে প্রদর্শিত আউটপুট পরিবর্তিত হয় date

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

#! /bin/bash

trap reexec 1
trap cleanup 2 3 9 15

CMD="$0"
ARGS=("$@")
statefile='/tmp/scriptA.state'
EXIT=1

reexec() { echo "Restarting..." ; exec "$CMD" "${ARGS[@]}"; }
cleanup() { rm -f $statefile; exit $EXIT; }
run_scriptB() { /path/to/scriptB; echo "scriptC" > $statefile; }
run_scriptC() { /path/to/scriptC; echo "stop" > $statefile;  }

while [ "$state" != "stop" ] ; do

    if [ -f "$statefile" ] ; then
        state="$(cat "$statefile")"
    else
        state='starting'
    fi

    case "$state" in
        starting)         
            run_scriptB
        ;;
        scriptC)
            run_scriptC
        ;;
    esac
done

EXIT=0
cleanup

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