এমভি: গন্তব্য বিদ্যমান না থাকলে কেবল ফাইলটি সরান


44

আমি ব্যবহার করতে পারি mv file1 file2একটি উপায় যে এটি শুধুমাত্র চলে আসে file1কাছে file2যদি file2বিদ্যমান নেই?

আমি চেষ্টা করেছিলাম

yes n | mv -i file1 file2

(এটি mvফাইল 2 কে ওভাররাইড করা উচিত কিনা এবং স্বয়ংক্রিয়ভাবে কোনও উত্তর দেওয়া উচিত কিনা তা জিজ্ঞাসা করতে দেয় ) তবে -iএটি গালি দেওয়ার পাশাপাশি আমাকে দুর্দান্ত ত্রুটি কোড দেয় না (সর্বদা 0 এর পরিবর্তে 141 সরানো হলে এবং সরানো না থাকলে অন্য কিছু)


3
pipefail141 এর প্রস্থান স্থিতি হিসাবে আপনার অবশ্যই বিকল্পটি থাকতে হবে yes, mvএখানে সাইনপাইপ পাওয়ার কোনও কারণ নেই।
স্টাফেন চেজেলাস

যদি ফাইল 2 ডিরেক্টরি হয় তবে এই পদ্ধতির ব্যর্থতাও (এটি ফাইল -1 কে ফাইল 2 ডিরেক্টরিতে স্থানান্তরিত করবে)। জিএনইউ এমভি এর -Tজন্য একটি রয়েছে ।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস যদি ইচ্ছা না করে তার থেকে প্রস্থান স্থিতির mvপরিবর্তে ব্যবহার করতে চান yesতবে সহজ সমাধান হতে পারেmv -i file1 file2 < <(yes n)
কাস্পারড

উত্তর:


63

mv -vn file1 file2। এই কমান্ডটি যা চাইবে তা করবে। আপনি চাইলে এড়িয়ে -vযেতে পারেন।

-v এটিকে ভার্জোজ করে তোলে - এমভি আপনাকে বলবে যে এটি সরানো হলে ফাইলটি সরানো হয়েছে (দরকারী, যেহেতু ফাইলটি স্থানান্তরিত হওয়ার সম্ভাবনা নেই)

-n কেবল ফাইল 2 এর অস্তিত্ব না থাকলে চলবে।

দয়া করে মনে রাখবেন তবে, যে এই POSIX নয় যেমন ThomasDickey উল্লেখ


2
তবে এটি পসিক্স নয় ।
থমাস ডিকি 10'15

1
@ থমাসডিকি কি পোসিক্স একেবারেই পারমাণবিক উপায়ে সমর্থন করে?
ফ্যাবিয়ান স্মিথেনার

3
ফ্যাবিয়ানের কাছে: সম্ভবত না, তবে প্রস্তাবিত উত্তরের মধ্যেও কীভাবে এটি রচিত তা নির্ভর করে সরঞ্জামগুলির মধ্যে একটি দৌড়ের সম্ভাবনা রয়েছে।
থমাস ডিকি

3
এটি জাতি থেকে মুক্ত বলে মনে হচ্ছে না, straceএটি (আমার সিস্টেমে) ব্যবহার করে: স্ট্যাট ("file2", 0x7ffe3e705d10) = -1 ENOENT (এরকম কোনও ফাইল বা ডিরেক্টরি নেই) lstat ("file1", {st_mode = S_IFREG | 0644, st_size = 0, ...}) = 0 lstat ("file2", 0x7ffe3e705a10) = -1 ENOENT (এ জাতীয় কোনও ফাইল বা ডিরেক্টরি নেই) পুনর্নবীকরণ ("file1", "file2") = 0 টি লুক (0, 0, SEEK_CUR) = -1 ESPIPE (অবৈধ সন্ধান)। তাই পুনরায় নাম ব্যবহার করা হবে বলে মনে হচ্ছে। আপনি যদি সত্যই এটি বিনা পয়সায় করতে চান তবে @ স্টাফেনচাজেলাস সমাধানটি সঠিক বলে মনে হচ্ছে।
ফ্যাবিয়ান স্মিথেনার 21

2
আমি অবাক হয়েছি কেন এটি ব্যবহার করে নাrenameat2
ফ্যাবিয়ান স্মিথেনার

16

mv -n

থেকে man mvএকটি গনুহ সিস্টেমে:

-n, --no-Clobber
কোনও বিদ্যমান ফাইল ওভাররাইট করে না

একটি ফ্রিবিএসডি সিস্টেমে:

-nএকটি বিদ্যমান ফাইল ওভাররাইট করবেন না। (-N বিকল্পটি পূর্ববর্তী -f বা -i বিকল্পগুলিকে ওভাররাইড করে))


10
if [ ! -e file2 ] && [ ! -L file2 ]
then
    mv file1 file2
# else echo >&2 there is already a file2 file.
fi

বা:

if ! ls -d file2 > /dev/null 2>&1
then
    mv file1 file2
fi

অস্তিত্ব না mvথাকলেই চলবে file2। মনে রাখবেন যে নিশ্চয়তা দেয় না যে একটি file2উপেক্ষিত হবে না কারণ একটি file2পরীক্ষা এবং তাদের মধ্যে সৃষ্টি করা হয়ে থাকতে পারে mv, কিন্তু মনে রাখবেন যে গনুহ অন্তত বর্তমান সংস্করণ এ mvসঙ্গে -iবা -nযে গ্যারান্টি হয় (দিতে হবে না যদিও race অবস্থা সংকীর্ণ সেখানে যেহেতু চেকটি সম্পন্ন হয়েছে mv)।

অন্য প্রান্তে, এটি পোর্টেবল, আপনাকে কেসের মধ্যে বৈষম্য তৈরি করতে দেয় এবং file2ফাইলের ধরণের (নিয়মিত, পাইপ, এমনকি ডিরেক্টরি ) নির্বিশেষে কাজ করে ।


3
এটি কি এমন কোনও রেসের শর্তটি প্রবর্তন করে যেখানে অস্তিত্ব চেক এবং সরানোর মধ্যে কোনও ফাইল লেখা যেতে পারে?
ফ্যাবিয়ান স্মিথেনার

3
আপনি যা কিছু করেন না কেন সর্বদা সম্ভাবনা।
মাজনকো

3
লিনাক্স এপিআইতে renameat2যা আপনি একটি RENAME_NOREPLACEপতাকা দিতে পারেন । আমি বিশ্বাস করি এটি পরমাণুভাবে ফাইলের অস্তিত্ব পরীক্ষা করে এবং তারপরে ফাইলটি সরিয়ে দেয়।
ফ্যাবিয়ান স্মিথেনার

ডিরেক্টরিগুলির জন্য -d, অথবা লিঙ্কগুলির জন্য -l, অথবা যে কোনও ফাইল টাইপের জন্য এমনকি
মাজেঙ্কো

পুনরায় নামটি রেস ফ্রি হতে পারে তবে এমভি কমান্ডের বাকি অংশটি তা নয়। যদি এটি মনে করে যে এটি লিঙ্কমুক্ত করার দরকার নেই তবে হঠাৎ করে নামটি ব্যর্থ হয়।
মাজনকো

8

lnপ্রদত্ত জিএনইউ সহ একটি রেস-মুক্ত পদ্ধতির file1ধরণের ডিরেক্টরি নেই :

ln -PT file1 file2 && rm file1

(কিছু নেটওয়ার্ক ফাইল সিস্টেমে বাগ বাদে) গ্যারান্টি দেয় যে কোনও file2ফাইল ওভাররাইড হবে না (বা এটি যদি file2টাইপ ডিরেক্টরিতে file1থাকে তবে তাতে সরানো হবে না), কারণ link()সিস্টেম কল, সিস্টেম কলের বিপরীতে rename()যদি ব্যর্থ হয় তবে লক্ষ্য বিদ্যমান।

যাইহোক, কোন মধ্যবর্তী রাষ্ট্র যেখানে ফাইল উভয় হিসাবে বিদ্যমান থাকবে file1এবং file2

-Tবিকল্প (সবসময় একটি করতে link("file1", "file2")এমনকি যদি file2টাইপ ডিরেক্টরি হয়) গনুহ-নির্দিষ্ট।

আপনি linkকমান্ডটি ব্যবহার করতে পারেন :

link file1 file2 && rm file1

তবে, যদি file1বাস্তবায়নের উপর নির্ভর করে file2কোনও সিমিলিংক হয় , তা হয় সেই সিমিলিঙ্কের জন্য একটি হার্ডলিঙ্ক বা সেই সিমিলিংকের লক্ষ্য (সোলারিসে, ব্যবহার করুন /usr/sbin/link, না /usr/xpg4/bin/link)।


2
তুমি কি জান যদি লিনাক্স API renameat2পতাকা দিয়ে RENAME_NOREPLACEপারমাণবিক হয়?
ফ্যাবিয়ান স্মিথেনার 21

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

0

test -e nameনামটি উপস্থিত থাকলে (ফাইল, ডিরেক্টরি বা সিমলিংক নির্বিশেষে) কোনটি সত্য হবে তা আপনি ব্যবহার করতে পারেন।

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

touch file
mkdir dir
ln -s file symlink
test -e file && echo file exists
test -e dir && echo dir exists
test -e symlink && echo symlink exists
test -e file || echo you wont see this echo
test -e doesnotexist || echo doesnotexist does not exist...

1
কিন্তু ln -s doesnotexist exists; test -e exists || echo "does it really not exist?"। উদাহরণস্বরূপ একই ln -s /var/spool/cron/crontabs/. exists(এবং আপনি রুট বা ক্রন্টব গ্রুপের সদস্য নন)।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.