অন্তর্নির্মিত বাশ দিয়ে `এক্সিকিউটিভ Run


9

আমি একটি শেল ফাংশন সংজ্ঞায়িত করেছি (আসুন এটি কল করুন clock), যা আমি অন্য কমান্ডের মোড়ক হিসাবে ব্যবহার করতে চাই time, যেমন ফাংশনের অনুরূপ , যেমন clock ls -R

আমার শেল ফাংশন কিছু কাজ সম্পাদন করে এবং এরপরে শেষ হয় exec "$@"

আমি এই ফাংশনটি শেল বিল্ট-ইনগুলির সাথেও কাজ করাতে চাই, উদাহরণস্বরূপ বিল্ট-ইন- clock time ls -Rএর ফলাফল আউটপুট করা উচিত time, এবং /usr/bin/timeসম্পাদনযোগ্য নয় not তবে execসর্বদা এর পরিবর্তে কমান্ডটি চালানো শেষ হয়।

আমি কীভাবে আমার বাশ ফাংশনটিকে মোড়ক হিসাবে কাজ করতে পারি যা শেল বিল্ট-ইনগুলি তর্ক হিসাবেও গ্রহণ করে?

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


আপনার স্পষ্টভাবে শেলটি ব্যবহার করা দরকার exec bash -c \' "$@" \'। প্রথম প্যারামিটারে আপনার কমান্ড শেল স্ক্রিপ্ট হিসাবে স্বীকৃত না হলে এটি সরাসরি চালিত বাইনারি হিসাবে ব্যাখ্যা করা হবে। বিকল্পভাবে এবং আরও সহজভাবে, কেবল আপনার আসল শেলটি থেকে মিস করুন execএবং কল করুন "@"
এএফএইচ

উত্তর:


9

আপনি একটি বাশ ফাংশন সংজ্ঞায়িত করেছেন। সুতরাং আপনি যদি ইতিমধ্যে একটি ব্যাশ শেলের মধ্যে থাকে যখন এই ফাংশনটি চালাবেন। সুতরাং যে ফাংশন তারপর সহজ চেহারা হতে পারে:

clock(){
  echo "do something"
  $@
}

এই ফাংশনটি ব্যাশ বিল্টিন, বিশেষ সংরক্ষিত শব্দ, আদেশ, অন্যান্য সংজ্ঞায়িত ফাংশন সহ আহবান করা যেতে পারে:

একটি উপনাম:

$ clock type ls
do something
ls is aliased to `ls --color=auto'

একটি বাশ বিল্টিন:

$ clock type type
do something
type is a shell builtin

অন্য ফাংশন:

$ clock clock
do something
do something

একটি নির্বাহযোগ্য:

$ clock date
do something
Tue Apr 21 14:11:59 CEST 2015

এই ক্ষেত্রে, দৌড়ানো $@এবং exec $@, যদি আমি জানি যে আমি একটি আসল কমান্ড চালাচ্ছি তার মধ্যে কি কোনও পার্থক্য রয়েছে ?
আনল

3
আপনি যখন ব্যবহার করবেন exec, কমান্ডটি শেলের পরিবর্তে। সুতরাং আর কোনও বিল্টইনস, এলিয়াস, বিশেষ সংরক্ষিত শব্দ, সংজ্ঞায়িত শব্দ নেই, কারণ এক্সিকিউটেবল সিস্টেম কলের মাধ্যমে কার্যকর করা হয় execve()। এই সিস্কল একটি এক্সিকিউটেবল ফাইল আশা করে।
বিশৃঙ্খলা

তবে বাহ্যিক পর্যবেক্ষকের দৃষ্টিকোণ থেকে এখনও কি তাদের আলাদা করা সম্ভব, যেমন exec $0একটি একক প্রক্রিয়া রয়েছে, যদিও $@এখনও দুটি রয়েছে still
আনল

4
হ্যাঁ, $@অভিভাবক হিসাবে চলমান শেল এবং শিশু প্রক্রিয়া হিসাবে কমান্ড রয়েছে। তবে আপনি যখন বিল্টিন, এলিয়াস এবং আরও কিছু ব্যবহার করতে চান, আপনাকে শেলটি সংরক্ষণ করতে হবে। অথবা একটি নতুন শুরু করুন।
বিশৃঙ্খলা

4

শেল বিল্টিন বা শেল কীওয়ার্ডটি চালু করার একমাত্র উপায় হ'ল নতুন শেল চালু করা কারণ এক্সিকিউটর "প্রদত্ত কমান্ড দিয়ে শেলটি প্রতিস্থাপন করে"। আপনার সাথে আপনার শেষ লাইনটি প্রতিস্থাপন করা উচিত:

IFS=' '; exec bash -c "$*"

এটি বিল্টিন এবং সংরক্ষিত উভয় শব্দের সাথে কাজ করে; নীতি একই।


3

প্রদত্ত কমান্ডের আগে যদি মোড়কের কোডটি সন্নিবেশ করা প্রয়োজন হয় তবে খুব প্রাথমিক পর্যায়ে প্রসারিত হওয়ার সাথে সাথে একটি উপনামটি কাজ করবে:

alias clock="do this; do that;"

এলিয়াস শব্দের স্থলে উপাধি প্রায় আক্ষরিক .োকানো হয়, সুতরাং অনুগমনটি ;গুরুত্বপূর্ণ - এটি clock time fooপ্রসারিত করে do this; do that; time foo

আপনি যাদু উপকরণগুলি তৈরি করতে এমনকি এটিকে উদ্ধৃত করে বাইপাস করতে অপব্যবহার করতে পারেন ।


কমান্ডের পরে কোড প্রবেশের জন্য , আপনি "DEBUG" হুক ব্যবহার করতে পারেন।

shopt -s extdebug
trap "<code>" DEBUG

বিশেষ করে:

shopt -s extdebug
trap 'if [[ $BASH_COMMAND == "clock "* ]]; then
          eval "${BASH_COMMAND#clock }"; echo "Whee!"; false
      fi' DEBUG

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

অন্য উদাহরণ হিসাবে, আপনি এটির command pleaseজন্য উপন্যাসটি এটি ব্যবহার করতে পারেন sudo command:

trap 'case $BASH_COMMAND in *\ please) eval sudo ${BASH_COMMAND% *}; false; esac' DEBUG

1

আমি এতক্ষণে যে সমাধান করতে পেরেছি তা হ'ল প্রথম যুক্তিটি হ'ল আদেশ, অন্তর্নির্মিত, বা কীওয়ার্ড এবং শেষ ক্ষেত্রে ব্যর্থ হয়েছে কিনা তা পার্থক্য করার জন্য কেস বিশ্লেষণ করা perform

#!/bin/bash

case $(type -t "$1") in
  file)
    # do stuff
    exec "$@"
    ;;
  builtin)
    # do stuff
    builtin "$@"
    ;;
  keyword)
    >&2 echo "error: cannot handle keywords: $1"
    exit 1
    ;;
  *)
    >&2 echo "error: unknown type: $1"
    exit 1
    ;;
esac

এটি হ্যান্ডেল করে না time, সুতরাং এর থেকে আরও ভাল (এবং আরও সংক্ষিপ্ত) সমাধান হতে পারে।

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