mv बनाम cp: परिणामी फ़ाइल के बारे में क्या अलग है?


3

मेरे पास एक बग था जहां कुछ एप्लिकेशन के लिए एक कॉन्फ़िगरेशन फ़ाइल को ठीक से शामिल नहीं किया जा रहा था, इसलिए फ़ाइल की समस्याग्रस्त रेखा को अलग करने की कोशिश करने के लिए, मैंने एक समय में पुरानी सामग्री को एक नई फ़ाइल में कुछ पंक्तियों में कॉपी किया।

अंत तक, मैंने फ़ाइल का एक सटीक डुप्लिकेट बनाया था, लेकिन पुराना अभी भी काम नहीं करेगा, जबकि नया बिल्कुल ठीक काम करता है।

इस बिंदु पर अधिक, यदि मैं mvउस फ़ाइल को स्थानांतरित करने के लिए कमांड का उपयोग करता हूं जहां से मैंने इसे उस स्थान पर संग्रहीत किया है जहां यह होना चाहता है, तो यह त्रुटियों का कारण बनता है। यदि मैं cpफ़ाइल को उस स्थान पर कॉपी करने के लिए उपयोग करता हूं जहां वह होना चाहता है, तो कोई त्रुटि नहीं है।

जाहिर है, सामान की तरह diff, fileया ls -l, दो फ़ाइलों के बीच कोई अंतर नहीं पता चलता है क्योंकि एक दूसरे की एक प्रति है, जैसा cpकि फ़ाइल की एक सटीक प्रतिलिपि बनाता है

मैं फ़ाइल के बारे में बहुत अधिक जानकारी साझा नहीं कर सकता क्योंकि यह एक काम की चीज़ है। लब्बोलुआब यह है कि कमांड cp fileA fileBऔर mv fileA fileB"अलग" फाइलबी का उत्पादन करते हैं। मेरा सबसे अच्छा अनुमान है कि फ़ाइलबी से कुछ सुपर निम्न-स्तरीय विशेषता पीछे छोड़ दी जाती है cp(यहां तक cp -pकि समान व्यवहार भी पैदा करता है)।

Mv cp से भिन्न क्या करता है, परिणामस्वरूप फ़ाइल की सटीक सामग्री से संबंधित है?

संपादित करें ls -l:

-rw-r--r--. 1 root root 3389 Aug  8 22:53 fileA
-rw-r--r--. 1 root root 3389 Aug  8 23:03 fileB

संपादित करें: आवेदन mysql है और फ़ाइल एक .cnf फ़ाइल है और इस कॉन्फ़िगरेशन फ़ाइल में आइटम जो विशेष रूप से रुचि थी, मास्टर-स्लेव डेटाबेस प्रतिकृति में उपयोग किए गए बाइनरी लॉग का नाम है। "त्रुटि" "आप बाइनरी लॉगिंग का उपयोग नहीं कर रहे हैं" क्योंकि कोई बाइनरी लॉग नहीं है, क्योंकि वह आइटम myqql द्वारा कभी भी "पढ़ा" नहीं गया था।

मेरी प्रारंभिक सोच यह थी कि कॉन्फ़िगरेशन फ़ाइल में एक सिंटैक्स त्रुटि थी जो पूरी चीज़ को पढ़ने में नहीं आने का कारण बन रही थी, जो कि मुझे पाठ के ब्लॉकों की प्रतिलिपि बनाकर मैन्युअल रूप से इसे फिर से बनाने के लिए ले जाती है।

संपादित करें: कहीं हो रही है ... अंत में फ़ाइलों के बारे में कुछ अलग है।

ls -lZ

-rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 server.cnf.bad
-rw-r--r--. root root unconfined_u:object_r:mysqld_etc_t:s0 server.cnf.good

क्या आपने फ़ाइल स्वामित्व की जाँच की है?
आर्ट गर्टनर

क्या आप cp -pएक नियमित उपयोगकर्ता के रूप में चलते हैं ? देखें कि सामान्य उपयोगकर्ता chownफ़ाइल क्यों नहीं बना सकता है ? सामान्य तौर पर, जब तक आप जड़ cp -pनहीं होंगे , स्वामित्व को संरक्षित नहीं करेंगे; mvमर्जी।
Kamil Maciorowski

1
cp -aइसके बजाय क्या cp -p?
Kamil Maciorowski

1
"ठीक से शामिल नहीं होने" का क्या मतलब है? यदि आपने कहा कि वास्तव में मूल के साथ क्या गलत हो सकता है तो यह मदद कर सकता है।
स्टीव स्मिथ

1
SELinux के साथ (ज्यादातर आरएचईएल और डेरिवेटिव पर डिफ़ॉल्ट), यहां तक ​​कि संदर्भ को भी ls -lZ
एबी

जवाबों:


3

टी एल; डॉ: एक प्रणाली है जहाँ में SELinux उपयोग में है, फ़ाइलों को सिस्टम द्वारा प्रयुक्त (यानी: डेमॉन) की नकल की जानी चाहिए या के साथ चारों ओर ले जाया cp -aZऔर mv -Zके बजाय cp -aऔर mv। यदि ऐसा नहीं किया गया था, तो किसी को डिफ़ॉल्ट SELinux संदर्भों को पुनर्स्थापित करने के लिए सिस्टम से पूछने के लिए बस restorecon -v -rया restorecon -v -F -rगंतव्य पर उपयोग करना चाहिए । restoreconस्क्रिप्ट के अंत में उपयोग करने के लिए हमेशा एक अच्छा विचार है जो मुख्य कॉन्फ़िगरेशन फ़ाइलों पर काम करता है।

आरएचईएल और इस प्रकार इसके अधिकांश डेरिवेटिव डिफ़ॉल्ट रूप से SELinux का उपयोग करते हैं

तो अपनी समस्या को हल करने के लिए, यदि आपका सिस्टम आरएचईएल आधारित है और mariadb-serverपैकेज का उपयोग कर रहा है, तो फ़ाइल सही जगह पर होने पर बस अंतिम चरण में करें :

# restorecon -v -F /etc/my.cnf.d/server.cnf
Relabeled /etc/my.cnf.d/server.cnf from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:mysqld_etc_t:s0

(ध्यान दें कि इसके बिना कॉन्फ़िगर करने के लिए -Fपरिवर्तित नहीं होगा । यह सामान्य प्रणालियों के लिए कोई फर्क नहीं पड़ेगा। अंतर का मेरा ज्ञान और यह क्यों मायने रखता है यह अभी तक नहीं जाता है)।unconfined_usystem_u

किसी अन्य स्थान पर फ़ाइल पर सही संदर्भ डालना केवल अधिक काम होगा। chconऐसा कर सकते हैं (या तो इसे इसके साथ बताते हुए -u -t, और अधिक संदर्भ को किसी अन्य फ़ाइल से कॉपी करके --reference):

# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad
# chcon -v -u system_u -t mysqld_etc_t /home/test/server.cnf.bad 
changing security context of '/home/test/server.cnf.bad'
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root system_u:object_r:mysqld_etc_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad

यदि आपको SELinux समस्याओं पर संदेह है, तो अपनी प्रक्रिया या फ़ाइल से संबंधित /var/log/audit/audit.logशब्द के साथ प्रविष्टियों की जांच करें denied। आप हमेशा अस्थायी रूप से SELinux को संचालन की अनुमति देने के लिए कह सकते हैं, और फिर उन्हें क्रमशः setenforce Permissiveऔर setenforce Enforcingव्यवहार की तुलना करने के लिए पुनर्स्थापित कर सकते हैं। Permissiveविशेष रूप से उत्पादन के लिए इसे मत छोड़ो ।

निम्नलिखित विभिन्न स्पष्टीकरण ...

कॉन्फ़िगरेशन फ़ाइलों पर काम करते समय उदाहरण और क्या किया जाना चाहिए

विभिन्न cpविकल्पों के साथ और mvएक SELinux सक्षम प्रणाली पर bahaviour का उदाहरण :

$ id
uid=1034(test) gid=1034(test) groups=1034(test)
$ pwd
/home/test
test@glasswalker:~$ ls -lZ foo
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 foo
$ cp foo /tmp/foo1
$ cp --preserve=context foo /tmp/foo2
$ cp -a foo /tmp/foo3
$ cp -aZ foo /tmp/foo4
$ mv foo /tmp/foo5
$ ls -lZ /tmp/foo?
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo1
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo2
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo3
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo4
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo5
$ touch bar
$ ls -lZ bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:49 bar
$ mv -Z bar /tmp
$ ls -lZ /tmp/bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:49 /tmp/bar

इसलिए सुरक्षा संदर्भों का उपयोग करते समय cp -aZया उपयोग mv -Zकरना ठीक रहता है और फिर भी अन्य विशेषताओं को संरक्षित करता है। चारों ओर एक स्क्रिप्ट मूविंग सिस्टम फाइलें हमेशा -Zकिसी भी cpया mvकमांड के लिए विकल्प का उपयोग करना चाहिए , या restoreconअनपेक्षित मुद्दों से बचने के लिए बस अपने अंतिम चरण में उपयोग करें ।

वो मतभेद क्यों?

mvआदेश एक संगत व्यवहार रहता है। यदि यह एक ही फाइल सिस्टम में हुआ है, तो निश्चित रूप से एक फाइल से जुड़ी कुछ भी, इसके सुरक्षा संदर्भ सहित, इसे बदल नहीं दिया जाएगा क्योंकि यह सिर्फ एक "नाम" है। इसलिए दो फाइल सिस्टमों में, जहां यह वास्तव में एक प्रति है, तब हटाएं, यह अपरिवर्तित पर भी कॉपी करता है जो फाइल से जुड़ा हुआ है और यह इसके सुरक्षा संदर्भ सहित, स्थिरता के लिए जानता है।

cpडिफ़ॉल्ट रूप से आदेश सिर्फ बनाता है एक नई फ़ाइल, तो यह फ़ाइल, हमेशा की तरह माता-पिता के SELinux संदर्भ विरासत में जब तक कि बेशक अन्यथा बताया साथ --preserve=contextजो में शामिल है -a। विकल्प --preserve=contextसे susbtracted किया जा सकता है तो सबसे अच्छा शर्त जब पूरे arborescences की नकल है , तो इसके बजाय अगर SELinux कोई फर्क नहीं पड़ता।-a-Z-aZ-a

फ़ाइल बनाते समय डिफ़ॉल्ट रूप से, जो कि सामान्य मामला है, यह नई फ़ाइल अपनी निर्देशिका SELinux संदर्भ को इनहेरिट करती है, यही कारण है कि सब कुछ ठीक काम करता है (ऑफ-टॉपिक: दुर्लभ स्थिति में फ़ाइल का संदर्भ केवल एक निर्देशिका के संदर्भ से भिन्न होना चाहिए क्योंकि इसके नाम पर शासन, कर्नेल परवाह नहीं करेगा, restorecondइसे संभालने के लिए डेमॉन जैसे कार्यक्रमों की आवश्यकता होगी)।

SELinux क्या है

SELinux एक अनिवार्य एक्सेस कंट्रोल मैकेनिज्म (उर्फ मैक ) है जो अन्य सभी मैकेनिज्म (यूनिक्स परमिशन उर्फ डीएसी , एक्सेस कंट्रोल उर्फ एसीएल इत्यादि) के अलावा उपयोग किया जाता है । जब कोई प्रक्रिया प्रक्रिया सुरक्षा संदर्भ में चलती है, तो यह जाँचने के लिए "नियम मैट्रिक्स" है कि क्या यह प्रक्रिया संदर्भ फ़ाइल के संदर्भ में पूछे गए ऑपरेशन (ओपन, रीड, राइट, एमएमएपी, ...) कर सकता है।

ओपी के मामले के लिए उदाहरण: यदि mysqldकेवल प्रक्रिया संदर्भ को ही कुछ फ़ाइल संदर्भ प्रकारों को एक्सेस करने की अनुमति दी जाती है, mysqld_etc_tलेकिन user_home_tतब शुरू mysqldकरना विफल रहेगा क्योंकि यह गलत user_home_tप्रकार के साथ इसकी कॉन्फ़िगरेशन फ़ाइल को नहीं पढ़ सकता है ।

सामान्य प्रणालियों पर, यह इंटरैक्टिव / लॉग-इन उपयोगकर्ता के लिए कोई मायने नहीं रखता है, क्योंकि इसकी सामान्य प्रक्रिया संदर्भ अपुष्ट है, जिसका अर्थ है कोई SELinux नियम लागू नहीं होगा। हर डेमॉन द्वारा शुरू systemdया अन्य इसी तरह तंत्र होगा एक प्रक्रिया संदर्भ, जिसके साथ जाँच की जा सकती प्राप्त psकी -Zविकल्प। SELinux पर चल रहे एक डेबियन सिस्टम पर उदाहरण:

# ps -Z -p $$
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 22498 pts/7 00:00:00 bash
# ps -Z -p $(pidof /sbin/getty)
LABEL                             PID TTY      STAT   TIME COMMAND
system_u:system_r:getty_t:s0     6158 tty1     Ss+    0:00 /sbin/getty 38400 tty1
system_u:system_r:getty_t:s0     6159 tty2     Ss+    0:00 /sbin/getty 38400 tty2
system_u:system_r:getty_t:s0     6160 tty3     Ss+    0:00 /sbin/getty 38400 tty3
system_u:system_r:getty_t:s0     6161 tty4     Ss+    0:00 /sbin/getty 38400 tty4
system_u:system_r:getty_t:s0     6162 tty5     Ss+    0:00 /sbin/getty 38400 tty5
system_u:system_r:getty_t:s0     6163 tty6     Ss+    0:00 /sbin/getty 38400 tty6

3

हां, एक प्रमुख अंतर है:

  • cp फ़ाइल की एक प्रतिलिपि बनाता है
  • mv (यदि आप फाइलसिस्टम के भीतर रहते हैं) बस डिस्क पर कुछ पॉइंटर्स को हिलाता है।

निम्नलिखित आज़माएँ:

touch a
ls -i a
cp a b
ls -i a b
mv a c
ls -i b c

आप देखेंगे कि b एक नई फ़ाइल है जिसमें एक नया इनकोड नंबर है, जहाँ c पुराने फ़ाइल के inode नंबर के साथ एक ही फ़ाइल है।

फिर भी, यह आपके अजीब व्यवहार की व्याख्या नहीं करता है।


मैंने इनोड पॉइंटर्स के बारे में भी सोचा था, लेकिन अगर वहां कुछ भी भ्रष्ट है, cpतो या तो ठीक से काम नहीं करना चाहिए, या टूटे हुए सामान को भी कॉपी करना चाहिए।
एंड्रयू पीयर्स

मैं cpकेवल गंतव्य नाम / पथ का उपयोग करके एक पूरी तरह से नया इनकोड बनाने की उम्मीद करूंगा । ध्यान रखें, इन सुविधाओं के लिए कोड लागू किए जाने के कई तरीके हैं। मुझे यकीन है कि उदाहरण के लिए cp एक कर्नेल विधि कहता है, पैरामीटर गुजर रहा है। उन पैरामोड्स इनोड से पढ़े या आये या नहीं आ सकते हैं, और यह संभव है कि भ्रष्टाचार विरोधी कोड एक छोर या दूसरे पर जोड़ा गया था, या केवल एक विशेष तर्क के लिए, या जो भी हो, इसलिए हम वास्तव में कोई भी नहीं बना सकते हैं इस समस्या के अलावा अन्य समस्याओं के बारे में गंभीर धारणा है कि आपके पास एक इनोड भ्रष्टाचार है, और cp ने एक नया इनोड बनाकर इसे ठीक किया।
फ्रैंक थॉमस

3

यह वही हो सकता है (आप एप्लिकेशन या इन त्रुटियों के बारे में बहुत कम जानकारी साझा करते हैं, इसलिए मैं केवल अनुमान लगा सकता हूं)।

लिनक्स में अनिवार्य फ़ाइल लॉकिंग असामान्य है । कॉल की तरह flock(2)का प्रबंधन सलाहकार ताले। इसका मतलब यह है कि कर्नेल ताले का ट्रैक रखता है, लेकिन उन्हें लागू नहीं करता है, यह अनुप्रयोगों का पालन करना है।

यदि कुछ लॉक होता है fileAऔर आपका एप्लिकेशन लॉक का पालन करता है, तो यह सेवा को मना कर सकता है। चलो मान लेते हैं कि यह क्या होता है।

मार्ग या नाम के बजाय लॉक इनोड को प्रभावित करता है। (नाम) बंद कर दिया चलती fileAकरने के लिए fileBएक एकल फाइल सिस्टम के भीतर inode लिए कुछ नहीं करता, फ़ाइल अभी तक बंद है, आवेदन अभी भी इसके साथ काम करने के लिए मना कर दिया। फ़ाइल को कॉपी fileBकरना अपने स्वयं के इनकोड के साथ एक अलग बनाता है जो लॉक नहीं है, एप्लिकेशन काम करता है।

(नोट: फ़ाइल को किसी अन्य फाइल सिस्टम में ले जाना वास्तव में प्रतिलिपि बनाना + हटाना है, इसलिए इसे लॉक को तोड़ देना चाहिए, यदि कोई हो)।


विशिष्ट अनुप्रयोग mysql है और मैं अपने आप को .cnf फ़ाइल के साथ संबंधित कर रहा हूँ। विशिष्ट लाइन लॉग-बिन = फ़ाइल-बिन.लॉग है, और mysql बाइनरी लॉग को सही तरीके से नहीं बना रहा था (इस प्रकार सभी मास्टर-स्लेव सामान को तोड़ रहा है)। मैं देखूंगा कि क्या mysql कोई फाइल लॉकिंग सामान करता है।
एंड्रयू पीयर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.