मुझे हटाई गई निर्देशिका से सीडी क्यों निकालना है?


19

मेरे सर्वर पर मेरे पास एक निर्देशिका संरचना है जो कुछ इस तरह दिख रही है:

/myproject/code

मैं आमतौर पर सर्वर के लिए एक ssh कनेक्शन और उस निर्देशिका में 'स्टैंड' है:

root@machine:/myproject/code#

जब मैं अपने कोड का एक नया संस्करण तैनात करता हूं, तो कोड निर्देशिका हटा दी जाती है, इसलिए मुझे छोड़ दिया गया है:

root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory

और एकमात्र समाधान जो मुझे मिला है वह है cd out और back in:

root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...

क्या मैं इससे बच सकता हूं? यह कुछ अजीब व्यवहार है। यदि आपके पास एक अच्छा स्पष्टीकरण है तो ऐसा क्यों होता है तो मैं इसकी सराहना करूंगा।


5
क्या आपने अपने कोड डायरेक्टरी में फाइलों को हटाने के बारे में सोचा है न कि कोड डायरेक्टरी में?
स्ट्रॉन्गबैड

9
आप गलत हैं कि नई बनाई गई निर्देशिका runपुरानी निर्देशिका के समान है। इसका केवल एक ही नाम और मूल निर्देशिका है। इसकी तुलना आप अपनी पुरानी कार से करने और सटीक उसी रंग और मॉडल की नई कार खरीदने से करते हैं: आप नहीं चाहते कि कार को किनारे कर दिया जाए और आशा है कि आप नई कार को अनचाहे खत्म कर देंगे?
एंथन

2
एंथन: मैं जो मानता हूं कि वह मार्ग है जो निर्देशिका की पहचान करता है। मेरे लिए "cd ../code" एक noop है। मुझे यह सुनने में बहुत दिलचस्पी है कि यह क्यों नहीं है।
मार्कस जोहानसन

2
@MarkusJohansson cd ../codeएक noop नहीं है। ..उस पथ के माता-पिता के लिए एक शॉर्टकट है जो आपके पास है, या जिसके पास है। यदि आपकी वर्तमान निर्देशिका हटा दी गई है, तो पैरेंट पथ अभी भी मौजूद हो सकता है, और इस मामले में मूल्यांकन करके पुन: पहुंच सकता है ..। उस निर्देशिका में 'कोड' नाम की निर्देशिका के लिए खोज की जाती है।
एंथन

2
@MarkusJohansson कोड हटाने और तार करने के बजाय, मैं अत्यधिक उपलब्ध किसी भी संस्करण नियंत्रण उपकरण का उपयोग करने की सलाह दूंगा। अपडेट को साझा करना अधिक आसान (केवल पुश या पुल) और गलती से गलत फ़ाइलों को हटाने के लिए कम विकल्प। और आप पुराने संस्करण को डिफ़ॉल्ट रूप से रखते हैं।
बर्नहार्ड

जवाबों:


26

मेरे लिए "cd ../code" एक noop है। मुझे यह सुनने में बहुत दिलचस्पी है कि यह क्यों नहीं है।

क्योंकि फाइलें और निर्देशिकाएं मूल रूप से फाइलसिस्टम इनोड हैं , नाम नहीं - यह शायद फाइलसिस्टम प्रकार के लिए विशिष्ट कार्यान्वयन विवरण है, लेकिन यह सभी एक्सट्रीम सिस्टम के लिए सही है, इसलिए मैं इसे यहां चिपकाऊंगा।

जब एक नई निर्देशिका codeबनाई जाती है, तो यह एक नए आईनोड से जुड़ी होती है, और यही वह जगह है। पहले से हटाई गई फ़ाइलों और निर्देशिकाओं का कोई रिकॉर्ड नहीं रखा गया है, इसलिए ऐसा कोई साधन नहीं है जिसके द्वारा सिस्टम यह जांच सके कि इनकोड किस चीज़ पर कब्जा करता था और शायद आसपास की चीजों को फेरबदल करता है ताकि यह फिर से वही हो; इस तरह की प्रणाली तेजी से अस्थिर हो जाएगी, और किसी भी मामले में, यह शायद कोई गारंटी नहीं है कि आप फिर से वहां वापस आएंगे - यह अवांछनीय होगा, क्योंकि इसका मतलब है कि अगर आप एक निर्देशिका बनाई गई है तो आप गलती से कहीं और समाप्त हो सकते हैं। यह आपका (वर्तमान में अप्रयुक्त) इनोड लेता है।

मुझे यकीन नहीं है कि यह अंतिम संभावना मौजूद है, या यदि आपके वर्तमान कार्य निर्देशिका को सौंपे गए हटाए गए निर्देशिका के इनकोड को ट्रैक किया गया है, ताकि अवधि के लिए इसे कुछ भी नहीं सौंपा जाएगा, आदि।


3
यहां इसका असली जवाब है।
karan.dodia

14

आपका शेल हर बार उस रास्ते पर नहीं जाता है cd, जो अगले कमांड को निष्पादित करने से पहले अंतिम कमांड के दौरान था।

आपने वर्तमान निर्देशिका को हटा दिया और उसी नाम से एक निर्देशिका बनाई, जो समान निर्देशिका नहीं है, बस उसी नाम / पथ के साथ कुछ है।

Nautilus और विंडोज एक्सप्लोरर जैसे फाइल ब्राउजर आमतौर पर डायरेक्टरी ट्री को "गो अप" कर देते हैं अगर कोई डायरेक्टरी लोकल फाइल सिस्टम पर डिलीट हो जाती है। हालाँकि यह नेटवर्क फ़ाइल सिस्टम के लिए हमेशा सही नहीं होता है, उस स्थिति में कभी-कभी डिलीट देखने को नहीं मिलता है और पुन: प्रकट होने से आप नई निर्देशिका में समाप्त हो सकते हैं।

cdअगली कमांड को निष्पादित करने से पहले एक शेल वर्तमान निर्देशिका में हो सकता है , मुझे ऐसा करने की कोई जानकारी नहीं है (या ऐसा करने के लिए कॉन्फ़िगर किया जा सकता है)।


फोल्ड इलस्ट्रेशन - सिद्धांत रूप में, यहां तक ​​कि एक फाइल सिस्टम भी मौजूद हो सकता है जहां पुरानी, ​​हटाई गई (या बिना लिंक की गई) निर्देशिका अभी भी मौजूद है और पढ़ने योग्य है, जबकि नया पहले से ही उपयोग में है। यह निर्देशिका के साथ अभ्यास में उपयोगी नहीं होगा, लेकिन फाइलों के साथ, यह बहुत आम है।
वोल्कर सिएगल

4

अधिकांश UNIX- जैसी प्रणालियों पर, एक प्रक्रिया के लिए "वर्तमान निर्देशिका" को उस निर्देशिका में इंगित करने वाले फ़ाइल विवरणक के रूप में कर्नेल में संग्रहीत किया जाता है। कर्नेल वास्तव में वर्तमान निर्देशिका के पथ को संग्रहीत नहीं करता है: यह जानकारी आपके शेल द्वारा ट्रैक की जाती है।

एक फाइलसिस्टम ऑब्जेक्ट (फाइल या डायरेक्टरी) केवल अच्छे के लिए नष्ट हो जाता है जब सभी फाइल सिस्टम लिंक चले जाते हैं, और उस ऑब्जेक्ट को इंगित करने वाले कोई फाइल डिस्क्रिप्टर नहीं होते हैं।

इसलिए, यदि कोई निर्देशिका हटा दी जाती है, जबकि अभी भी एक प्रक्रिया है जो इसे अपनी वर्तमान कार्यशील निर्देशिका के रूप में रखती है, तो प्रक्रिया की cwdनिर्देशिका निर्देशिका को वास्तव में हटाए जाने से बचाए रखेगी। फाइलसिस्टम लिंक को निर्देशिका में जोड़ता है (मूल प्रविष्टि में इसकी प्रविष्टि, और इसकी सभी सामग्री) चली जाएगी, लेकिन निर्देशिका स्वयं "ज़ोंबी" के एक प्रकार के रूप में मौजूद रहेगी। इस बीच, आप पुराने के रूप में एक ही स्थान पर एक नई निर्देशिका बना सकते हैं, जो पूरी तरह से अलग फाइल सिस्टम ऑब्जेक्ट है, लेकिन जो एक ही पथ साझा करता है।

इस प्रकार, जब आप करते हैं cd ../code(या कई गोले पर cd .), आप वास्तव में फाइलसिस्टम पदानुक्रम का पता लगा रहे हैं और पुराने पते पर रहने वाली नई निर्देशिका में जा रहे हैं ।

सादृश्य से, एक निर्देशिका को हटाने से ऐसा होगा जैसे घर से कूड़ा डंप करना (पिछले पते पर संबंध तोड़ना)। अगर वहाँ अभी भी कोई रहता था (इसे अपने रूप में इस्तेमाल करते हुए cwd), तो उन्हें घर से बाहर निकलने से पहले छोड़ना होगा। इस बीच, पुराने पते पर एक नया घर बनाया जा सकता है।


0

@ एंथन ने स्पष्ट कारण बताए, ऐसा क्यों होता है
समाधान के रूप में आप उपनाम का उपयोग कर सकते हैं , उदाहरण के लिए:

alias 1234='PROJECT=`pwd`; cd $PROJECT ; ./run'

बैश के लिए उपनाम ~ / .bashrc में keept हैं


0

वर्तमान कार्यशील निर्देशिका की पुष्टि इनकोड संख्या के आधार पर की जाती है, न कि आप वहां पहुंचने के लिए। चूँकि आप बैश का उपयोग कर रहे हैं, आप उसी नाम की नई निर्देशिका के लिए $ PWD का उपयोग निम्नानुसार कर सकते हैं:

सीडी $ पीडब्ल्यूडी

समझाने के लिए, मैंने एक डमी की तैनाती की कमान बनाई:

set -x
cd ~/tmp
rm -rf code
mkdir code
echo echo hello from $* > code/run
chmod +x code/run

पहली तैनाती के लिए बनाया गया, कोड को कोड किया और फिर सामग्री की जाँच की ls -laiताकि आप इनोड देख सकें:

ianh@abe:~/tmp$ ./,deploy first
++ cd /home/ianh/tmp
++ rm -rf code
++ mkdir code
++ echo echo hello from first
++ chmod +x code/run
ianh@abe:~/tmp$ cd code
ianh@abe:~/tmp/code$ ls -lai
total 12
22945913 drwxr-xr-x  2 ianh ianh 4096 Apr  9 23:12 .
22937618 drwxrwxr-x 14 ianh ianh 4096 Apr  9 23:12 ..
22939455 -rwxr-xr-x  1 ianh ianh   22 Apr  9 23:12 run

अब दूसरी तैनाती चलाते हैं

ianh@abe:~/tmp/code$ ../,deploy 2nd
++ cd /home/ianh/tmp
++ rm -rf code
++ mkdir code
++ echo echo hello from 2nd
++ chmod +x code/run

और निर्देशिका सामग्री की जाँच करें ... अब निर्देशिका में कुछ भी नहीं है! इतना भी नहीं '।' तथा '..'! इसमें से आप देख सकते हैं कि बैश '..' निर्देशिका प्रविष्टि का उपयोग नहीं कर रहा है जब आप cd ..'से चलाते हैं' .. 'अब मौजूद नहीं है - मैं इसके $ PWD हैंडलिंग के अपने हिस्से को मानता हूँ। कुछ अन्य / पुराने शेल cd ..इस स्थिति में संभाल नहीं करते हैं , आपको पहले एक निरपेक्ष पथ पर जाना होगा।

ianh@abe:~/tmp/code$ ls -lai
total 0

Cd $PWDऔर फिर से प्रयास करें:

ianh@abe:~/tmp/code$ cd $PWD
ianh@abe:~/tmp/code$ ls -lai
total 12
22945914 drwxr-xr-x  2 ianh ianh 4096 Apr  9 23:12 .
22937618 drwxrwxr-x 14 ianh ianh 4096 Apr  9 23:12 ..
22939455 -rwxr-xr-x  1 ianh ianh   20 Apr  9 23:12 run
ianh@abe:~/tmp/code$ ./run
hello from 2nd

ध्यान दें कि वर्तमान निर्देशिका (।) के लिए इनकोड कैसे बदल गया?

यदि आपकी परिनियोजित स्क्रिप्ट पुरानी निर्देशिका को किसी अन्य नाम पर ले जाती है, उदाहरण mv code code.$$के लिए, ऊपर स्क्रिप्ट को परिनियोजित करती है, तो ./runकाम करेगी, लेकिन जब तक आप उपयोग नहीं करते तब तक आप पुराने कोड को cd $PWDचला रहे होंगे , नया नहीं।

ianh@abe:~/tmp/code$ ./run
hello from 2nd
ianh@abe:~/tmp/code$ ../,deploy 3rd
++ cd /home/ianh/tmp
++ '[' -d code ']'
++ mv code code.9629
++ mkdir code
++ echo echo hello from 3rd
++ chmod +x code/run
ianh@abe:~/tmp/code$ ./run
hello from 2nd
ianh@abe:~/tmp/code$ cd $PWD
ianh@abe:~/tmp/code$ ./run
hello from 3rd

कैपिस्ट्रानो का उपयोग करने का एक ही मुद्दा है (उनके पास वर्तमान नाम से वर्तमान रिलीज के लिए एक सिमलिंक है), इसलिए मैं उत्पादन / मंचन क्षेत्रों के साथ-साथ RAIL_ENV को उचित रूप से सेट करने के लिए उपनाम का उपयोग करता हूं:

alias cdp='export RAILS_ENV=production; echo RAILS_ENV=$RAILS_ENV ; cd /var/www/www.example.com/current'
alias cds='export RAILS_ENV=staging; echo RAILS_ENV=$RAILS_ENV ; cd /var/www/staging.example.com/current'

0

मेरा मानना ​​है कि मार्ग वह है जो निर्देशिका की पहचान करता है।

किसी चीज़ का रास्ता यह है कि आप वहाँ कैसे पहुँचें, न कि खुद चीज़। आपके बिस्तर का रास्ता आपके कमरे के माध्यम से हो सकता है, लेकिन एक बार जब आप बिस्तर पर होते हैं, अगर कोई इसे उठाता है और इसे बाहर ले जाता है, तो आप अब अपने कमरे में नहीं हैं।


0

स्व-निहित जवाब नहीं है, लेकिन मेरे पास एक अतिरिक्त बिंदु है, जिसमें टिप्पणी करने वाला मार्जिन बहुत छोटा था।

इस विचार के लिए बेहतर अनुभव प्राप्त करने के लिए कि प्रासंगिक फ़ाइल सिस्टम में एक निर्देशिका सिर्फ एक पथ से अधिक है, किसी अन्य प्रक्रिया की वर्तमान कार्यशील निर्देशिका को स्थानांतरित करने का प्रयास करें: एक शेल में, एक इंटरैक्टिव पायथन सत्र शुरू करें:

$ python
>> import os
>> os.getcwd()
'/home/you/hocus'

फिर, किसी अन्य शेल पर जाएं और उस निर्देशिका को स्थानांतरित करें:

$ cd /home/you
$ mv hocus pocus

मूल पर वापस जाएं:

$ अजगर
>> ओएस आयात करें
>> os.getcwd ()
'/ घर / आप / धोखा'
>> os.getcwd ()
'/ घर / आप / देना'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.