কেন `watch`` হোমস এর তালিকা বিষয়বস্তু তৈরি করে?


13

আমি আমার /tmp/ডিরেক্টরিতে ফাইল সংখ্যা দেখার চেষ্টা করছি । এর জন্য আমি ভেবেছিলাম এই আদেশটি কার্যকর হবে:

watch sh -c 'ls /tmp/|wc -l'

তবে এটি এমন মনে হয় যেন lsকোনও যুক্তি নেই work যথা, আমি আছি ~, এবং আমি সেখানে ফাইলের সংখ্যা পাই /tmp/। আমি একটি পরিশ্রম পেয়েছি, যা কাজ করে বলে মনে হচ্ছে:

watch sh -c 'ls\ /tmp/|wc -l'

তবে কেন আমার মধ্যে lsএবং এর মধ্যবর্তী স্থানটি পালাতে হবে /tmp/? কমান্ডটি কীভাবে রূপান্তরিত হবে watchযাতে lsআউটপুটটি ফিড করা হয় wc, কিন্তু /tmp/যুক্তি হিসাবে পাস করা হয় না ls?


1
watch "sh -c 'ls /tmp | wc -l'"এই কমান্ডটি করার ফলে পছন্দসই প্রভাব পাওয়া উচিত। এটি ত্রুটি দেখছে না, চেষ্টা করুন sh -c ls /tmpএবং আপনি আপনার হোম ডিরেক্টরিটি পাবেন (তবে কেন আমি জানি না ...)
জ্যাকব মিনশাল

8
কোনও উত্তর নয় তবে আপনি watchভুলভাবে ব্যবহার করছেন youআপনি যে কমান্ডটি পাস করেছেন watchতা বদলে ফেলা watchহবে sh -c, সুতরাং আপনি কার্যকরভাবে sh -cদু'বার করছেন ।
ইরুভর

আপনি জানতে আগ্রহী তাহলে আপনি কটাক্ষপাত থাকতে পারে উৎস
মিশাস 20

1
@JacobMinshall কেন সহজবোধ্য: /tmpএকটি যুক্তি sh, সেই ক্ষেত্রে, কোনো আর্গুমেন্ট প্রাপ্ত করতে ls
চার্লস ডাফি

উত্তর:


17

পার্থক্যটি এর মাধ্যমে দেখা যেতে পারে strace:

$ strace -ff -o bq watch sh -c 'ls\ /tmp/|wc -l'
^C
$ strace -ff -o nobq watch sh -c 'ls /tmp/|wc -l'
^C
$ grep exec bq* | grep sh
bq.29218:execve("/usr/bin/watch", ["watch", "sh", "-c", "ls\\ /tmp/|wc -l"], [/* 54 vars */]) = 0
bq.29219:execve("/bin/sh", ["sh", "-c", "sh -c ls\\ /tmp/|wc -l"], [/* 56 vars */]) = 0
bq.29220:execve("/bin/sh", ["sh", "-c", "ls /tmp/"], [/* 56 vars */]) = 0
$ grep exec nobq* | grep sh
nobq.29227:execve("/usr/bin/watch", ["watch", "sh", "-c", "ls /tmp/|wc -l"], [/* 54 vars */]) = 0
nobq.29228:execve("/bin/sh", ["sh", "-c", "sh -c ls /tmp/|wc -l"], [/* 56 vars */]) = 0
nobq.29229:execve("/bin/sh", ["sh", "-c", "ls", "/tmp/"], [/* 56 vars */]) = 0

ব্যাককোয়িট ক্ষেত্রে, ls /tmpএকক আর্গুমেন্ট হিসাবে পাস করা -cহয় sh, যা প্রত্যাশা অনুযায়ী চলে। এই ব্যাককোয়টি ব্যতীত কমান্ডটি পরিবর্তে শব্দ বিভক্ত হয় যখন watchসঞ্চালিত হয় shযা পরিবর্তিত হয় sh, যাতে কেবলমাত্র lsযুক্তি হিসাবে পাস করা হয় -c, যার অর্থ সাব-সাবটি shকেবল একটি খালি lsকমান্ড চালাবে , এবং বর্তমান কাজকর্মের বিষয়বস্তু তালিকাভুক্ত করবে ডিরেক্টরি।

তাহলে, কেন জটিলতা sh -c ...? কেন কেবল চালাবেন না watch 'ls /tmp|wc -l'?


ওহ, straceএটি চেষ্টা করার কথা ভাবেনি।
Ruslan

1
আসলে, হ'ল ব্যাককোট (বা ব্যাক-টিক)। এই প্রশ্নটি \ সম্পর্কে, যা ব্যাকস্ল্যাশ।
জি-ম্যান বলছেন 'মনিকাকে পুনরায় ইনস্টল করুন'

@Ruslan: আমি এই মন্তব্য পোস্ট এই উত্তরে হয়েছে কারণ এটি একটি মন্তব্য এই উত্তরে । thrig বলে "ইন backquote মামলা, ls /tmpহয় ..." এবং "এই ছাড়া backquote , কমান্ড ...", এবং ব্যবহার bqএবং nobqফাইলের নাম, যখন সব সময় উল্লেখ ব্যাকস্ল্যাশ আপনার ls\ /tmpকমান্ড।
জি-ম্যান বলছেন 'পুনরায় ইনস্টল করুন মনিকা'

8

watchকমান্ডের দুটি প্রধান বিভাগ রয়েছে (যেগুলির মধ্যে পর্যায়ক্রমে কমান্ডগুলি চালানো হয়, watchএটি একটি মানক কমান্ড নয়, এমন কোনও সিস্টেম রয়েছে যেখানে watchফ্রিবিএসডি-তে অন্য টিটি লাইনে স্নুপিংয়ের মতো সম্পূর্ণ আলাদা কিছু ঘটে)।

এমন একটি যা ইতিমধ্যে শেলের সাথে তার যুক্তিগুলির সংমিশ্রণটি শেলের সাথে স্থান করে দেয় (এটি কার্যকর কল হয় sh -c <concatenation-of-arguments>) এবং একটি যে শেলটি না ছাড়াই নির্দিষ্ট আর্গুমেন্টগুলি দিয়ে নির্দিষ্ট কমান্ডটি চালায়।

আপনি প্রথম পরিস্থিতিতে আছেন, সুতরাং আপনার কেবল প্রয়োজন:

watch 'ls /tmp/|wc -l'

যখন তুমি কর:

watch sh -c 'ls /tmp/|wc -l'

আপনার watchআসলে চালানো:

sh -c 'sh -c ls /tmp/|wc -l'

এবং ইনলাইন স্ক্রিপ্টটি sh -c ls /tmp/চলছে lsযেখানে $0রয়েছে /tmp/(সুতরাং lsতর্ক ছাড়াই চালানো হয় এবং বর্তমান ডিরেক্টরি তালিকাভুক্ত হয়)।

watchপ্রথম বিভাগের কিছু বাস্তবায়ন (লিনাক্সের প্রোপস-এনজি-র মতো) -xতাদের watchদ্বিতীয় বিভাগের মতো আচরণ করার জন্য একটি বিকল্প গ্রহণ করে । সুতরাং সেখানে, আপনি করতে পারেন:

watch -x sh -c 'ls /tmp/|wc -l'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.