سؤال

لدي اثنين من الدلائل في نفس الدليل الأصل.دعوة الوالد الدليل قاعدة والأطفال الدلائل ألفا و برافو.أريد أن محل ألفا مع برافو.أبسط طريقة هي:

rm -rf alpha
mv bravo alpha

الأمر mv هو الذرية ، ولكن rm-rf لا.هناك طريقة بسيطة في باش إلى الذرة محل ألفا مع برافو?إن لم يكن, هل هناك طريقة معقدة?

إضافة:

بالمناسبة, انها ليست مشكلة مستعصية على الحل إذا كان الدليل لا وجود لفترة قصيرة.هناك مكان واحد فقط أن يحاول الوصول ألفا ، فإنه يتحقق إذا كان ألفا موجود قبل أن تفعل أي شيء حاسم.إذا لم يكن كذلك ، فإنه يعطي رسالة خطأ.ولكن سيكون من الرائع إذا كان هناك طريقة للقيام بذلك.:) ربما هناك طريقة لتعديل inodes مباشرة أو شيء...

هل كانت مفيدة؟

المحلول

يمكنك القيام بذلك إذا كنت تستخدم روابط الرمزية:

دعونا نقول ألفا هو الارتباط الرمزي إلى دليل alpha_1 و تريد تبديل الارتباط الرمزي إلى نقطة alpha_2.هنا هو ما يبدو قبل التبديل:

$ ls -l
lrwxrwxrwx alpha -> alpha_1
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2

لجعل ألفا الرجوع إلى alpha_2 استخدام ln-nsf:

$ ln -nsf alpha_2 alpha
$ ls -l
lrwxrwxrwx alpha -> alpha_2
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2

الآن يمكنك إزالة القديمة الدليل:

$ rm -rf alpha_1

لاحظ أن هذا ليس في الواقع تماما الذرية العملية ، ولكن ذلك يحدث بسرعة كبيرة منذ "في" القيادة سواء unlinks ثم على الفور بإعادة الارتباط الرمزي.يمكنك التحقق من هذا السلوك مع strace:

$ strace ln -nsf alpha_2 alpha
...
symlink("alpha_2", "alpha")             = -1 EEXIST (File exists)
unlink("alpha")                         = 0
symlink("alpha_2", "alpha")             = 0
...

يمكنك تكرار هذا الإجراء المطلوب:على سبيل المثالعندما يكون لديك الإصدار الجديد ، alpha_3:

$ ln -nsf alpha_3 alpha
$ rm -rf alpha_2

نصائح أخرى

الحل النهائي هو الجمع بين symlink - إعادة تسمية-نهج:

mkdir alpha_real
ln -s alpha_real alpha

# now use "alpha"

mkdir beta_real
ln -s beta_real tmp 

# atomically rename "tmp" to "alpha"
# use -T to actually replace "alpha" instead of moving *into* "alpha"
mv -T tmp alpha

بالطبع التطبيق الوصول إلى ألفا يجب أن تكون قادرة على التعامل مع روابط الرمزية تغيير في المسار.

على التقاط ديفيد الحل هنا, وهو تماما الذرية ...المشكلة الوحيدة التي قد تواجهها هي أن -T الخيار mv غير POSIX و حتى بعض POSIX انظمة التشغيل قد لا تدعم ذلك (فري, سولاريس, الخ.... http://pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html).مع تعديل طفيف ، وهذا النهج يمكن تغييرها بالكامل الذرية ، والمحمولة في جميع POSIX انظمة التشغيل:

mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./

لexaple عن طريق: http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/

إذا كنت تقصد الذرية عبر كل العمليات, لا أعتقد ذلك.الأقرب ليكون:

mv alpha delta
mv bravo alpha
rm -rf delta

ولكن هذا سوف لا تزال لديها نافذة صغيرة فيها ألفا لم تكن موجودة.

لتقليل احتمال حدوث أي شيء يحاول استخدام ألفا في حين أنه لا يمكن (إذا كان لديك السلطة):

nice --20 ( mv alpha delta ; mv bravo alpha )
rm -rf delta

والتي سوف نرفع العملية الخاصة بك الأولوية إلى حد كبير حين mv عمليات يحدث.

إذا كان كما تقول في الإضافة ، هناك مكان واحد فقط أن يتحقق ألفا و الأخطاء إذا لم يكن هناك يمكنك تغيير هذا الرمز إلى عدم الخطأ على الفور ، ولكن حاول مرة أخرى في وقت قصير (بسهولة الفرعية الثانية لمدة سنتين mv عمليات) - هذه المحاولات أن تخفف من أي مشكلة إلا إذا كنت استبدال ألفا جدا في كثير من الأحيان.

تستخدم منفصلة مضمونة الذرية ، العملية بمثابة إشارة.

إذا إيجاد و إزالة الملفات العمليات الذرية:

1) إنشاء ملف يسمى "سيمافور".

2) إذا وفقط إذا كان هذا هو النجاح (لا تتعارض مع القائمة ملف) ، هل العملية (أي عملية ألفا أو نقل دليل ، اعتمادا على عملية)

3) rm سيمافور.

على سكليتي قسم الوثائق ملف تأمين التزامن في SQLite الإصدار 3 كما وصف مكتوب تصاعد تأمين بروتوكول التحكم المتزامن القراءة الحصرية الكتابة ، الاستعادة بعد الحادث.بعض هذه الأفكار تنطبق هنا.

هذا ينبغي أن تفعل خدعة:

mkdir bravo_dir alpha_dir
ln -s bravo_dir bravo
ln -s alpha_dir alpha
mv -fT bravo alpha

strace mv-قدم برافو ألفا يظهر:

rename("bravo", "alpha")

والتي تبدو جميلة الذرية لي.

منذ لينكس 3.15 الجديد ، renameat2 نظام الاتصال يمكن أن الذرة تبادل مسارين على نفس نظام الملفات.ومع ذلك ، ليس هناك حتى glibc المجمع بعد, ناهيك عن coreutils طريقة الوصول إليه.لذلك سوف ننظر بشيء من هذا القبيل:

int dirfd = open(".../base", O_PATH | O_DIRECTORY | O_CLOEXEC);
syscall(SYS_renameat2, dirfd, "alpha", dirfd, "bravo", RENAME_EXCHANGE);
close(dirfd);
system("rm -rf alpha");

(بالطبع, يجب عليك أن تفعل السليم معالجة الخطأ.... الخ– انظر هذا جوهر أكثر تطورا renameat2 المجمع.)

أن قال – symlink حل المذكورة من قبل الآخرين هو أسهل المحمولة إلا إذا bravo بالفعل موجود و يجب أن الذرة تحديث ذلك ، انتقل مع symlink بدلا من ذلك.

حتى إذا كنت الوصول إلى inodes مباشرة سيظل هناك أي وسيلة الذرة مبادلة inode القيم في فضاء المستخدم.

القلق بشأن الذرية طبيعة العملية لا معنى له.الأمر هو الوصول إلى ألفا الأخرى المهمة لن تكون الذرية على أي حال.

Oddthinking هو إشارة النهج هو السبيل الوحيد للذهاب.

إذا كنت لا تستطيع تعديل مهمة أخرى ثم سيكون لديك للتأكد من انها لا تعمل قبل أن تعمل على استبدال.

أنا لا أعتقد أن هناك أي الذرية طريقة للقيام بذلك.أفضل رهان هو أن تفعل شيئا من هذا القبيل:

mv alpha delme
mv bravo alpha
rm -rf delme

شيء أن نأخذ في الاعتبار هو أنه إذا كان لديك العملية أي من الملفات في ألفا مفتوحة عند نقل/حذف تحدث عملية لن تلاحظ أي بيانات مكتوبة سوف تضيع عند إغلاق الملف و أخيرا إزالتها.

mv و في يمكن أن تستخدم في عمليات نووية.لقد استعملت في(1) نشر تطبيقات الويب الذرة.

الطريقة الصحيحة استبدال الارتباط الرمزي مع ln-nsf

ln -nsf <target> <link_name>

على سبيل المثال

$ mkdir dir1
$ mkdir dir2
$ ln -s dir1 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:45 mylink -> dir1
$ ln -nsf dir2 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:46 mylink -> dir2

ومن الممكن أيضا استبدال أي جزء من المحتوى في وقت واحد في بعض البادئة (Z هنا) باستخدام unionfs-fuse:

لماذا لا تفعل شيئا مثل:

rm -rf alpha/*
mv bravo/* alpha/
rm -rf bravo/

هذا يعني أن كل شيء في ألفا هو تدمير ألفا أبدا يحصل حذف جميع محتويات الحصول على نقلها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top