গন্তব্য নির্দিষ্ট না করে `এমভি ./* What কী করে?


27

আমি দুর্ঘটনাক্রমে রিটার্ন কী চাপানোর আগে গন্তব্য নির্দিষ্ট করতে ভুলে গিয়েছিলাম। mv ./*গন্তব্য নির্দিষ্ট না করে বর্তমান ডিরেক্টরিতে থাকা ফাইল এবং ডিরেক্টরিগুলি কোথায় স্থানান্তরিত করে?



4
"আমি অবাক হয়েছি যে mv1 টি যুক্তি গ্রহণ করে" এটি হয় না। এটি প্রসারিত করার পরে শেলটি এতে সমস্ত আর্গুমেন্ট গ্রহণ করে *
glglgl

উত্তর:


41

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

এখানে কিছু বিক্ষোভ রয়েছে:

দুটিরও বেশি ফাইল এবং শেষ যুক্তি একটি ফাইল

$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory

দুটিরও বেশি ফাইল এবং শেষ যুক্তি একটি ডিরেক্টরি

$ mkdir d1 d2 d3
$ touch a b c
$ mv -v *
'a' -> 'd3/a'
'b' -> 'd3/b'
'c' -> 'd3/c'
'd1' -> 'd3/d1'
'd2' -> 'd3/d2'

দুটি ফাইল

$ touch a b
$ mv -v *
'a' -> 'b'

অারোও ব্যাখ্যা

শেলটি বিশ্বব্যাপী ( *) আর্গুমেন্টে প্রসারিত করে mv। গ্লোবটি সাধারণত বর্ণানুক্রমিক ক্রমে প্রসারিত হয়। mvফাইল এবং ডিরেক্টরিগুলির তালিকা সর্বদা দেখায়। এটি গ্লোব নিজেই দেখেনি।

কমান্ড mvদুটি ধরণের চলন সমর্থন করে। এক mv file ... directory। অন্যটি হ'ল mv old-file-name new-file-name(বা mv old-file-name directory/new-file-name)।


30

প্রথমে আমি একটি পরীক্ষার বেস করব - 5 ফাইল এবং একটি ফোল্ডার:

touch file1 file2 file3 file4 file5
mkdir folder

এরপরে আমি একটি পরীক্ষা কমান্ড চালাব। -vবিকল্প নির্দিষ্ট করে আমি প্রতি কমান্ড শেল, executes থেকে প্রিন্ট করা চাই যে stderr-xবিকল্প নির্দিষ্ট করে আমি চাই যে একই মুদ্রিত stderr- কিন্তু আমি এটি সম্পন্ন চান পর কমান্ড মূল্যায়ন করা হয় কিন্তু আগে শেল করে সঞ্চালিত হয়।

sh -cxv 'echo mv *'

আউটপুট

echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder

সুতরাং আপনি দেখতে পাচ্ছেন যে আমি কমান্ডটি শেল ফিড করব এবং শেলটি প্রসারিত হওয়ার পরে কার্যকর করা echo mv *কমান্ডটি সেই ফাইল এবং ফোল্ডারের সমস্তটি অনুসরণ করবে। *echo mv

ডিফল্টরূপে শেলটি গ্লোবগুলি প্রসারিত করে :

sh -cxv 'echo file[1-5]'

আউটপুট

echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5

এটি set [+-]fগ্লোব ফাংশনের ফলাফল :

sh -cxvf 'echo file[1-5]'

আউটপুট

echo file[1-5]
+ echo 'file[1-5]'
file[1-5]

সুতরাং আপনি যখন শেলটিতে একটি কমান্ড চালান যখন ডিফল্ট বিকল্পগুলির সাথে কনফিগার mv *করা শেলের মতো শেল *শব্দের মধ্যে প্রসারিত হয় বর্তমান ডিরেক্টরিতে সমস্ত ফাইলের একটি আর্গুমেন্টের তালিকা স্থানীয় অনুসারে বাছাই করা হয়। এটা তোলে প্রাপ্ত syscall করে exec(ve)জন্য mv (মূলত) এই যুক্তি তালিকা যোগ করা হয়। সুতরাং mvহিসাবে শেল তাদের globs এবং তাদের বাছাই করে এর সব আর্গুমেন্ট পায়। straceএই প্রভাবগুলি দেখার জন্য করা ছাড়াও , আপনি আবার ডিবাগ আউট ব্যবহার করতে পারেন যেমন:

sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT

আউটপুট

sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder

এবং বহনযোগ্য:

( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1

আউটপুট

: /mv/file1/file2/file3/file4/file5/folder/

মূলত, শেল, executes mvডিরেক্টরি বিষয়বস্তু সঙ্গে (এবং যদি এটা খালি না থাকে নামের সাথে শুরু সঙ্গে ফাইল / ফোল্ডার সহ না .) তার যুক্তি তালিকা হিসাবে। mvPOSIX এর চূড়ান্ত যুক্তিটিকে ডিরেক্টরি হিসাবে ব্যাখ্যা করার জন্য নির্দিষ্ট করা হয় যদি এটি দুটিরও বেশি আর্গুমেন্টের সাথে আহ্বান করা হয় - একইভাবে lnহয় (কারণ, প্রকৃতপক্ষে, তারা অন্তর্নিহিত ফাংশনে অবিশ্বাস্যরূপে একই সরঞ্জাম)

echoযদিও যথেষ্ট :

sh -cxv 'mv *' ; ls

আউটপুট

mv *
+ mv file1 file2 file3 file4 file5 folder
folder/

সমস্ত ফাইল চূড়ান্ত যুক্তিতে স্থানান্তরিত হয়েছিল - কারণ এটি একটি ফোল্ডার। এখন যদি এটি ফোল্ডার না হয়?

sh -cxv 'cd *; mv *'; ls . *

আউটপুট

cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory

.:
folder/

folder:
file1  file2  file3  file4  file5

এই হল কিভাবে POSIX নির্দিষ্ট করে mv যে ক্ষেত্রে আচরণ করা উচিত:

mv [-if] source_file target_file

mv [-if] source_file... target_dir

প্রথম সংক্ষিপ্ত আকারে, mvইউটিলিটি Source_file অপারেন্ড দ্বারা চিহ্নিত ফাইলটিকে টার্গেট_ফায়াল দ্বারা নির্দিষ্ট গন্তব্যে নিয়ে যাবে । এই প্রথম সংশ্লেষ ফর্মটি ধরে নেওয়া হয় যখন চূড়ান্ত অপারেন্ডটি কোনও বিদ্যমান ডিরেক্টরিকে নাম দেয় না এবং কোনও বিদ্যমান ডিরেক্টরিকে উল্লেখ করে প্রতীকী লিঙ্ক না করে। এই ক্ষেত্রে, যদি সোর্স_ফাইলে একটি ডিরেক্টরি-নির্দেশিত ফাইলের নাম এবং টার্গেট_ফায়াল একটি শেষের /slashঅক্ষর দিয়ে শেষ হয় তবে এটিকেmv ত্রুটি হিসাবে বিবেচনা করা হবে এবং কোনও সোর্স_ফাইলে অপারেশনগুলি প্রক্রিয়া করা হবে না।

দ্বিতীয় mvসংশ্লেষ আকারে, Source_file অপারেন্ডের নামে চিহ্নিত প্রতিটি ফাইলকে টার্গেট_ডির অপারেন্ড দ্বারা বিদ্যমান ডিরেক্টরিতে একটি গন্তব্য ফাইলে স্থানান্তরিত করা হবে , বা লক্ষ্য_ডির একটি বিদ্যমান ডিরেক্টরিকে উল্লেখ করে একটি প্রতীকী লিঙ্ক থাকলে উল্লেখ করা হবে। প্রতিটি উত্স-ফাইলের গন্তব্য পথ হ'ল লক্ষ্য নির্দেশকের সংমিশ্রণ, লক্ষ্যটি /slashযদি একটিতে শেষ না হয় তবে একটি একক অক্ষর /slashএবং উত্স_ফায়ালের শেষ পথের উপাদানটি । এই দ্বিতীয় ফর্মটি ধরে নেওয়া হয় যখন চূড়ান্ত অপরেন্ড একটি বিদ্যমান ডিরেক্টরিটির নাম দেয়।

সুতরাং যদি *প্রসারিত হয়:

  • দুটি ফাইল

    • আপনার কেবল একটি ফাইল থাকা উচিত যা renamedদ্বিতীয়টির পরে প্রথম থেকে দ্বিতীয় unlinked
  • এক বা একাধিক ফাইল সর্বশেষে একটি ডিরেক্টরি বা তার একটি লিঙ্ক অনুসরণ করে

    • আপনার কেবলমাত্র একটি ডিরেক্টরি বা একটিতে একটি লিঙ্ক থাকা উচিত, এটি যেখানে তার পিতামাতার সমস্ত পূর্ববর্তী বিষয়বস্তু সবে সরে গেছে।
  • আর কিছু

    • আপনার একটি ত্রুটি বার্তা এবং ত্রাণ একটি সন্তোষজনক দীর্ঘশ্বাস থাকা উচিত।

1
হ্যাঁ, পুরানো shজিনিসটি ব্যবহার করে , আমি এটি দিয়ে ডিবাগিংয়ের কথা ভুলে গিয়েছিলাম, তবে আমার মূল প্রশ্নটি সম্পর্কে, এর অর্থ এই যে সমস্যাটি শেল নয় mv? এটি খুব বাজে, এটি আমি প্রাথমিকভাবে ভাবার চেয়ে সহজ তবে এটি একটি বাস্তব ফাঁদ।
ব্যবহারকারী 2485710

5
@ user2485710, মূল কথাটি হ'ল ইউনিক্সে শেলটি কমান্ডের সাথে কমান্ড লাইন আর্গুমেন্টগুলি পাস করার আগে ওয়াইল্ডকার্ডগুলি প্রসারণের জন্য দায়বদ্ধ। উইন্ডোজে প্রতিটি কমান্ডকেই ওয়াইল্ডকার্ডগুলি প্রসারিত করতে হয়। এটি ইউনিক্স শেলগুলিকে উন্নত ওয়াইল্ডকার্ড সুবিধা প্রদান করতে অনুমতি দেয় যা কোনও কমান্ডের সাথে কাজ করে।
সিজেএম

2
@ মেকজারভেল এই সত্যটি দিয়েছিলেন যে এই ফাইলগুলি এত গুরুত্বপূর্ণ ছিল না যে আমি নিজেকে পরিষ্কার করার জন্য ছুটে এসেছি এবং পরবর্তী পদক্ষেপে চলে এসেছি, তবে আমি এখন আমার প্রথম পোস্ট / প্রশ্নের আমার সম্পাদনাতে উপস্থিত জিনিসগুলি নিশ্চিত করতে পারি।
ব্যবহারকারী 2485710

6
@ মাইকজার্ভ টিএল; ডাঃ, *একক যুক্তি নয় কি? রাইট? :)
বার্নহার্ড

1
@ বার্নহার্ড - আসলে, এটিই আমি একমাত্র মামলাটি আবরণ করি নি - কারণ এটি হতে পারে।
মাইকজার্ভ

18

প্রথমে শেলটি ./*বর্তমান ডিরেক্টরিতে সমস্ত ফাইলগুলিতে প্রসারিত হয় (বিন্দু দিয়ে শুরু হওয়া ফাইলগুলি বাদে)।

  • যদি কোনও বা কেবল একটি ফাইল না থাকে: mvব্যর্থ হয়
  • যদি দুটি ফাইল থাকে: প্রথমটি দ্বিতীয়টিতে স্থানান্তরিত হয় (যার ফলে হারিয়ে যায়)
  • যদি দুটিরও বেশি ফাইল থাকে:
    • যদি শেষটি একটি ডিরেক্টরি হয়: সমস্ত ফাইল এই ডিরেক্টরিতে সরানো হবে
    • অন্যথায় mvব্যর্থ।

1
ধন্যবাদ। কোনটি উপ-ডিরেক্টরি "সর্বশেষ" তা কীভাবে বলবেন?
টিম

7
echo ./*আপনার শেলটি কোন ক্রম ব্যবহার করে (সাধারণত বর্ণানুক্রমিক) কেবল কল করুন do
জোফেল

যদি এটি একটি ফাইলের সাথে ব্যর্থ হয় তবে এটি কেন এটি বলে না?
নুমেনন

@ নুমেনন আমি আপনার মন্তব্য বুঝতে পারি না। mvএকটি ত্রুটি বার্তা প্রদান করে যদি এটি কেবল একটি যুক্তি দিয়ে ডাকা হয়।
জোফেল

তুমি ঠিক. আমার ইতিহাস থেকে একই আদেশ এখন দেয় missing destination file operand after *filename*যদিও গতকাল তা হয়নি।
নুমেনন

4

আপনি যখন টাইপ করবেন mv ./*, ./*কার্যকর করার আগে আপনার শেলটি প্রসারিত হবে mv

কয়েকটি বিষয় লক্ষণীয়:

  • যদি ./*2 টিরও কম আর্গুমেন্টে প্রসারিত হয় mv, তবে যৌক্তিকভাবে ত্রুটি তৈরি করবে।
  • ./* বর্তমান ডিরেক্টরিতে উপস্থিত প্রতিটি ফাইলে (ডিরেক্টরি সহ) বিস্তৃত হবে এবং বিন্দু দিয়ে শুরু হবে না।
  • ./*আপনার শেলের ডকুমেন্টেশন পড়ে কী প্রসারিত হবে তা আপনি নিয়ন্ত্রণ করতে পারেন (বিষয়টিতে man 7 globপ্রবেশের একটি বিষয়)। বিভিন্ন শেলের বিভিন্ন বিকল্প থাকবে।

1

কি করে mv *?

একটি সংক্ষিপ্ত উত্তর এখানে:

শেলটি ওয়াইল্ডকার্ডকে *ডিরেক্টরি বিষয়বস্তুর তালিকায় প্রসারিত করে । তারপরে শেলটি পুরো তালিকাটি কমান্ডে প্রেরণ করে। কমান্ড কখনই দেখে না *

কমান্ডটি mv file1 file2 ... filen directoryফাইল 1 ... ফাইলনকে ডিরেক্টরিতে স্থানান্তরিত করবে।

উদাহরণ

এখানে আমি তিনটি ফাইল সমন্বিত একটি ডিরেক্টরি ডিরেক্টরি তৈরি করি

$ mkdir t
$ cd t
$ echo a>a; echo b>b; echo c>c
$ ls
a  b  c

আপনি একক ফাইলে একাধিক ফাইল সরাতে পারবেন না

$ mv *
mv: target `c' is not a directory

একটি সাব ডিরেক্টরি ডিরেক্টরি যুক্ত করা যাক

$ mkdir d

আপনি একাধিক ফাইলকে একটি সাবডাইরেটরিতে স্থানান্তর করতে পারেন

$ mv *
$ ls
d
$ ls d
a  b  c

কমান্ডটির সাথে mv file1 file2 ... filen directoryকিছু করার খুব কম সম্ভাবনা রয়েছে *
মাইকজার্ভ

@ মাইক: আমার উত্তরটি নির্দেশ করে যে শেল প্রসারণের শেষ পর্যায়ে কার্যকরভাবে পরবর্তীটিকে পূর্বের মধ্যে রূপান্তরিত করে। এটি না জেনেই ওপি'র বিভ্রান্তির মূল বলে মনে হয়।
রেডগ্রিটিব্রাইক

হ্যাঁ, কিন্তু আমার পয়েন্ট শেল প্রসারিত না হবে *মধ্যে file dirযদি না কিছু লোকেল যা হয় dঅনুসরণ f
মাইকজার্ভ

@ মিমকিজার: এখানে এমন লোকেল রয়েছে, আমার উদাহরণটি পুটি থেকে সেন্টস 5.6 জিএনইউ / লিনাক্স সিস্টেমের সাথে সংযোগ স্থাপনের একটি কাটা পেস্ট।
রেডগ্রিটিব্রিক 15

এটা কোন লোকেল? আপনার উদাহরণ a b c dযা না file ... dir। আমি শুধু এ সব মন্তব্য কারণ আপনার সাজানোর জন্য যে কোন জায়গায় উল্লেখ না এবং বল শুধু তাই *হয়ে file ... dirযা ঘটে না।
মাইকজার্ভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.