শেল প্রোফাইল এবং বর্তমান ডিরেক্টরি হুকগুলি ব্যবহার করে কীভাবে শেল-কমান্ড রান করবেন (উদাহরণস্বরূপ ডাইরেনভ)


9

আমি পেতে চেষ্টা করছি shell-commandএবং async-shell-commandআমার মধ্যে প্রোগ্রাম একটি দম্পতি সাথে অঙ্গীভূতভাবে সংহত করার .bashrcফাইল, বিশেষভাবে direnv এই উদাহরণে হবে।

আমি দেখেছি যে আমি কাস্টমাইজ করা থাকলে shell-command-switch, আমার প্রোফাইলটি লোড করার জন্য আমি শেল প্রক্রিয়াগুলি পেতে পারি যেন এটি একটি নিয়মিত ইন্টারেক্টিভ লগইন শেল:

(সেটেক শেল-কমান্ড-স্যুইচ (খাঁটি কপি "-ic"))
(সেটেক স্পষ্ট-বাশ-আরগস '("-ic" "রফতানি EMACS =; স্টিটি ইকো; ব্যাশ"))

আমিও ব্যবহার করছি Exec-পথ-থেকে-শেল

বলুন আমার ~/.bashrcসাথে একটি ফাইল রয়েছে:

...

eval "$ (ডিরেক্টনভ হুক $ 0)"
প্রতিধ্বনি "ফু"

ভিতরে ~/code/fooআমার .envrcসাথে একটি ফাইল রয়েছে:

PATH = $ PWD / bin: export PATH রফতানি করুন
প্রতিধ্বনি "বার"

আমি চালানোর প্রয়োজন হলে M-x shellসঙ্গে default-directoryসেটে ~/code/foo, একটি ব্যাশ শেল সঠিকভাবে আমার প্রোফাইল লোড আমার পথ যে যোগ করার জন্য direnv হুক চালানো হবে:

ডিরেক্টরি: লোড করা .envrc
বার
ডিরেক্টনভ: এক্সপোর্ট ~ PATH AT
~ / কোড / foo $ প্রতিধ্বনি $ PATH
/ ব্যবহারকারী / ব্যবহারকারী নাম / কোড / ফু / বিন: / ইউএসআর / স্থানীয় / বিন: ... # বাকী AT প্যাথ

তবে যদি default-directoryএখনও থাকে ~/code/fooএবং আমি M-! echo $PATHচালিয়ে যাই তবে এটি সঠিকভাবে আমার .bashrc লোড করে তবে বর্তমান ডিরেক্টরিটির ডিরেক্টনভ হুকটি কার্যকর করে না:

foo বিন্যাস
/ usr / স্থানীয় / বিন: ... # বাকী। PATH ./bin ছাড়া

আমি চালালে আমি একই ফলাফল পেতে M-! cd ~/code/foo && echo $PATH

আমি কীভাবে কোনও পরামর্শ বা হুক করতে পারি shell-commandবা start-processএটি এমন আচরণ করতে পারি যেন এটি কোনও ইন্টারেক্টিভ শেল বাফার থেকে প্রেরণ করা হয়েছিল?


আপনার ডিরেক্টনভ হুক কেমন দেখাচ্ছে? যদি এটি ~ / .bashrc এ সংজ্ঞায়িত করা হয় এবং আপনি বিস্মৃত হন (setq shell-command-switch "-ic")তবে ~ / .bashrc এ থাকা প্রতিটি কমান্ডের সাথে এটি মূল্যায়ন করা উচিত।
7:58

আমার eval "$(direnv hook $0)"। / .Bashrc এর লাইনটি । এটি কার্যকর হচ্ছে, তবে আপনি যখন কোনও .envrcফাইলের সাথে একটি নির্দিষ্ট ডিরেক্টরিতে থাকবেন তখন যে পদ্ধতিটি বরখাস্ত করা উচিত তা নয়।
ওয়েমমন্ডো 25:51

.envrcফাইল কিছুই মূল্যায়ন করা হয়? বা রফতানি করা হয় না শুধুমাত্র পরিবেশ পরিবর্তনশীল? আপনি কি দয়া করে একটি পূর্ণ উদাহরণ সরবরাহ করতে পারেন যাতে আমি এটি পুনরুত্পাদন করার চেষ্টা করতে পারি?
rekado

@ রেকাডো - এটি একবার দেখার জন্য ধন্যবাদ পুনরুত্পাদন করার জন্য আরও স্পষ্ট হতে আমি আমার প্রশ্ন আপডেট করেছি।
ওয়েইমন্ডো

উত্তর:


5

এটি ইমাক্সের সাথে তবে ব্যাশের সমস্যা বলে মনে হচ্ছে না। shell-commandখোলের call-processউপর চালিত করে এবং আর্গুমেন্টগুলি পাস করে। আমি এটি একটি নিয়মিত শেল দিয়ে চেষ্টা করেছি:

bash -ic "cd ~/code/foo && echo $PATH"

~/.bashrcউত্সাহিত, কিন্তু ডাইরনভ হুক চালানো হয় না। যখন direnv hook bashমৃত্যুদন্ড কার্যকর করা হয়, তখন একটি ফাংশন _direnv_hookআউটপুট হয় এবং এতে চাপ দেওয়া হয় PROMPT_COMMAND

_direnv_hook() {
  eval "$(direnv export bash)";
};
if ! [[ "$PROMPT_COMMAND" =~ _direnv_hook ]]; then
  PROMPT_COMMAND="_direnv_hook;$PROMPT_COMMAND";
fi

আমি সন্দেহ করি যে PROMPT_COMMANDকেবল কাজ করবে না। যদিও এটি কোনও সমস্যা নয়, কারণ এটি _direnv_hookসত্যই সহজ। আমরা কেবল eval $(direnv export bash)শেল কমান্ডে প্রিপেন্ড করতে পারি এবং এটি কাজ করবে:

(let ((default-directory "~/code/foo/"))
  (shell-command "eval \"$(direnv export bash)\" && echo $PATH"))

এটি বার্তাগুলির বাফারে সংযুক্ত পাথটি মুদ্রণ করবে। বিকল্পভাবে, এর সাথে সম্পাদন করুন M-!:

cd ~/code/foo && eval "$(direnv export bash)" && echo $PATH

(setq shell-command-switch "-ic")এটি কাজ করার জন্য আপনার দরকার নেই ।


ধন্যবাদ, এটি সত্যই আমাকে সঠিক পথে চালিত করতে সহায়তা করেছে। আমি এমন একটি সমাধান eval "$(direnv export bash)"খুঁজছিলাম যার মধ্যে এলিস্প যুক্ত হওয়া জড়িত না , তবে এটি অত্যন্ত সহায়ক ছিল এবং আমাকে সঠিক পথে রাখল।
ওয়েমমন্ডো

5

রানিং eval "$(direnv hook $0)"এমন একটি ফাংশনকে সংজ্ঞায়িত করে যা মধ্যে লুকিয়ে থাকে $PROMPT_COMMAND, যা bash -icপ্রম্পট না থাকায় বাশ চালানোর সময় কখনই ডাকা হয় না । আপনি লাইনটি পরিবর্তন করতে পারেন:

eval "$(direnv hook $0)"

প্রতি:

eval "$(direnv hook $0)" && _direnv_hook

স্পষ্টভাবে হুক ফাংশন কল করতে।

সম্পাদনা: ঠিক উপলব্ধি করা রেকাডো খুব অনুরূপ উত্তর দিয়েছে answer


এটিই সবচেয়ে সংক্ষিপ্ত উত্তর যা আমার অপরিচিতাকে নির্দেশ করে যে কীভাবে ডার্নিভ কাজ করে $PROMPT_COMMAND
ওয়েমমন্ডো

4

ডায়রনভ হুক ব্যবহার করে কীভাবে কাজ করে তা নির্দেশ করার জন্য রেকাডো এবং এরিককে ধন্যবাদ জানাই $PROMPT_COMMAND। যেহেতু shell-commandপ্রম্পট ব্যবহার করে না, তাই এটি কার্যকর করা হচ্ছে না।

এরিক এর উত্তর সঙ্গে শেল কমান্ড কলিং আমার উদাহরণে কাজ করে M-!সঙ্গে default-directoryসেট, এটি হবে নিম্নলিখিত উদাহরণে কাজ নাও:

(let ((default-directory "~/code/"))
  (shell-command "cd ~/code/foo && echo $PATH"))

কিছুটা গুগল করার পরে, কমান্ড কার্যকর হওয়ার আগে কিছু কার্যকর করার জন্য আমি ব্যাশে একটি প্রিক্সেক হুক তৈরির একটি উপায় খুঁজে পেয়েছি । আমি এই ধারণাটি নিয়েছি এবং আমার প্রয়োজনের দিকনির্দেশনার জন্য ফিট করে আছি। আমার। / .Bashrc এর প্রাসঙ্গিক অংশটি এখন কেমন দেখাচ্ছে তা এখানে:

eval "$(direnv hook $0)"
direnv_preexec () {
  [ -n "$COMP_LINE" ] && return # don't execute on completion
  [ "$BASH_COMMAND" \< "$PROMPT_COMMAND" ] && return # don't double execute on prompt hook
  eval "$(direnv export bash)"
}
trap "direnv_preexec && $BASH_COMMAND" DEBUG

0

আজকাল আপনি সম্ভবত https://github.com/wbolster/emacs-direnv ব্যবহার করতে চাইবেন

এটি হুকের অনুরূপ কাজ করে যা আপনার শেলের মধ্যে ডিরেক্টনভ ইনস্টল করে। বর্তমান ডিরেক্টরিটির সঠিক পরিবেশটি কী ডাইরনভ রাজ্যগুলির সাথে মেলে তা অনুরোধের জন্য ইম্যাক্স এনভায়রনমেন্ট আপডেট করা হয় (বা স্বয়ংক্রিয়ভাবে বাফারগুলি স্যুইচ করার সময়) is

পরিবর্তন করে exec-pathএবং process-environmentইমাসগুলি আপনার শেলের মতো আচরণ করবে: সঠিক পথ থেকে এবং সঠিক পরিবেশের সাথে প্রোগ্রামগুলি সম্পাদন করবে।

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