সাধারণ লিনাক্স কমান্ডের সাথে নিখুঁত সিমিলিংকে আপেক্ষিক সিমিলিংকে রূপান্তর করুন


29

আমি একটি পাথ ভিতরে সম্পূর্ণ উপ-ফাইলসিস্টেম আছে /home/user/systemডিরেক্টরি সহ স্ট্যান্ডার্ড লিনাক্স গঠন ধারণকারী /bin, /home, /root, /usr, /var, /etc, ...

এই সাব-ফাইল সিস্টেমে প্রতীকী লিঙ্ক রয়েছে, হয় আপেক্ষিক বা পরম। আপেক্ষিক সিমলিংকগুলি ঠিক আছে, তারা সাব-ফাইল-সিস্টেমের অধীনে থাকে /home/user/system। তবে পরম symlinks সমস্যাযুক্ত কারণ তারা সাব-ফাইল সিস্টেমের বাইরের একটি লক্ষ্যকে দেখায়।

একটি উদাহরণ হিসাবে আমরা নিম্নলিখিত হিসাবে একটি পরম syMLink ধরে (উপ-ফাইল সিস্টেমের ভিতরে দেখা যায়):

/usr/file1 -> /usr/lib/file1

সামগ্রিক ফাইল সিস্টেমে আমাদের একটি লিঙ্ক রয়েছে /home/user/system/usr/file1যা এখন /usr/lib/file1সাব-ফাইল সিস্টেমের /home/user/system/usr/lib/file1 ভিতরে থাকা ফাইলের পরিবর্তে সাব-ফাইল সিস্টেমের বাইরে একটি ফাইলকে নির্দেশ করে ।

আমি একটি সাধারণ স্ক্রিপ্ট চাই, বিশেষত একটি একক কমান্ড লাইন (rsync, chroot, সন্ধান করুন, ...) যা প্রতিটি পরম সিমিলিংকে আপেক্ষিকের সাথে রূপান্তর করে।

প্রদত্ত উদাহরণে, সেই আপেক্ষিক লিঙ্কটি হয়ে যাবে

/usr/file1 -> ../usr/lib/file1

4
: এই প্রশ্ন সমাধান করার চেষ্টা আগ্রহী তাদের জন্য, এখানে থেকে তাই প্রয়াস একটি 250k rep'd ব্যবহারকারী এর stackoverflow.com/questions/2564634/... । এই থ্রেডে বেশ কয়েকটি সম্ভাব্য সমাধান রয়েছে, তবে প্রত্যেকের নির্দিষ্ট পরিস্থিতি রয়েছে যা এটির সাথে আচরণ করে এবং অন্যরা তা করে না।
slm

উত্তর:


20

মার্ক লর্ডের symlinksইউটিলিটি সহ (অনেক বিতরণের দ্বারা প্রদত্ত; যদি আপনার এটি না থাকে তবে উত্স থেকে এটি তৈরি করুন ):

chroot /home/user/system symlinks -cr .

বিকল্পভাবে, এমন একটি সিস্টেমে যেগুলির একটি readlinkকমান্ড রয়েছে এবং একটি -lnameপ্রিডিট রয়েছে find(সতর্কতা: অরক্ষিত কোড):

cd /home/user/system &&
find . -lname '/*' -exec ksh -c '
  for link; do
    target=$(readlink "$link")
    link=${link#./}
    root=${link//+([!\/])/..}; root=${root#/}; root=${root%..}
    rm "$link"
    ln -s "$root${target#/}" "$link"
  done
' _ {} +

এটি একটি দুর্দান্ত সমাধান হবে! যাইহোক, _ {} +অনুসন্ধানের শেষে অভিব্যক্তিটির অর্থ কী? এছাড়াও, আমি একটি ভুল পান find: paths must precede expression: kshযা জানার জন্য (যেমন পথ বলে মনে হচ্ছে না preceeds ksh অভিব্যক্তি)।
অ্যালেক্স

@Alex _হয় $0শেল স্নিপেট জন্য, এবং {} +আর্গুমেন্টের তালিকায় যা হয়ে দ্বারা প্রতিস্থাপিত হয় $1, $2ইত্যাদি, যা for link; do …(এটা সমার্থক এর উপর loops for link in "$@"; do …)। ত্রুটিটি findএকটি টাইপোর কারণে হয়েছে (আমি কোনওভাবে যুক্তির আশেপাশে একক উদ্ধৃতিগুলির পরিবর্তে ব্যাককোটগুলি টাইপ করতে সক্ষম হয়েছি -lname)।
গিলস 'তাই মন্দ হওয়া বন্ধ করুন'

এখন স্ক্রিপ্টটি চলছে তবে প্রত্যাশার মতো নয়। সম্ভবত আমি যথেষ্ট সঠিক ছিল না, আমি প্রশ্ন আপডেট করেছি।
অ্যালেক্স

@ অ্যালেক্স কি সমস্যা? আমি মনে করি নীতিটি সঠিক, তবে আমি কিছু কোডিং ভুল করেছি। আপনি চেষ্টা করেছেন symlinks? এটি আপনার সমস্যার সমাধান করবে - এটি মূলত এটির জন্য ডিজাইন করা হয়েছিল (বিরক্তি সহকারে আপনাকে এটি ক্রোয়েটেড চালাতে হবে ( ফাকেচরুটটি কৌশলটি করা উচিত))।
গিলস 'এস-অশুভ হওয়া বন্ধ করুন'

1
আমি অতিরিক্ত কিছু ইনস্টল করার প্রয়োজন ছাড়াই বাক্সের বাইরে সমাধানের দৃ strongly়তার সাথে দৃ .়তা জ্ঞাপন করছি।
অ্যালেক্স

4

খাঁটি বাশ এবং কোরিউটিলগুলি, ../পথে অযৌক্তিকভাবে ছাড়াই আপেক্ষিকের প্রতিলিপি পরিবর্তন করে:

find . -type l | while read l; do
    target="$(realpath "$l")"
    ln -fs "$(realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target")" "$l"
done

তুমি বদলাতে পারো:

  • find .থেকে find /path/to/directoryযে ডিরেক্টরির মধ্যে symlinks রূপান্তর করতে
  • ln -fsথেকে echo ln -fsএকটি শুষ্ক চালানোর জন্য

ব্যাখ্যা:

  • target="$(realpath "$l")" - সিমলিংক লক্ষ্যটির নিখুঁত পথ সন্ধান করে
  • ln -fs- সিমলিংক তৈরি করে ( -s), জোর করে ( -f) বিদ্যমান পুনর্লিখন
  • realpath -s "$l" - নিজেই সিমলিংকের নিখুঁত পথ সন্ধান করে
  • dirname "$(realpath -s "$l")" - সিমলিংকযুক্ত ডিরেক্টরিটির নিখুঁত পথ খুঁজে পায়
  • realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target" - অন্য কথায় সিমলিংকের সাথে সম্পর্কিত লক্ষ্যের সন্ধান করে: পরমার্থকে আপেক্ষিক পথে রূপান্তরিত করে

1
আমি ifভাঙা লিঙ্কগুলি এড়ানোর জন্য একটি ধারা যুক্ত করার পরামর্শ দেব ।
ফুয়েনফুন্ডাচজিজি

0

এই বাশ স্নিপেটটি এটি করা উচিত। প্রথম ফর্মটি কী করবে তা মুদ্রণ করবে; দ্বিতীয়টি এটি করবে। ফলাফলটি ধ্বংসাত্মক হিসাবে আমি সাবধানতার সাথে পর্যালোচনা করব - ln -fবিদ্যমান লিঙ্কটি ওভাররাইট করে।

TOP=/home/user/system
cd $TOP
find * -type l -print | while read l; do echo ln -sf $TOP$(readlink $l) $l; done
find * -type l -print | while read l; do      ln -sf $TOP$(readlink $l) $l; done

খালি জায়গাগুলির সাথে নামের জন্য এটি ব্যর্থ হবে এই বিষয়টি ছাড়াও, এটি কি ভুল উপায়ে নয়? এটি পরম পথে উপসর্গ করে?
ফুয়েনফুন্ডাচটজিগ

0

এখানে একটি শুদ্ধ sh সমাধান।

সিডি / হোম / ব্যবহারকারী / সিস্টেম এবং&
খুঁজে। -নাম '/ *' |
l পড়ার সময়; করা
  প্রতিধ্বনি ln -sf $ (প্রতিধ্বনি $ (প্রতিধ্বনি | l | সেড 'গুলি | / [^ /] * | / .. | জি')) $ (পঠন লিঙ্ক $ l) | সেড 's / ..........//' ) $ l
সম্পন্ন |
SH

0

আপেক্ষিক লিঙ্কগুলিতে পরম রূপান্তরকরণকে sshfs সমর্থন করে যা ssh এর মাধ্যমে দূরবর্তী ডিরেক্টরিগুলি মাউন্ট করে।

আদেশটি হ'ল: আছে

sudo sshfs <remote_user>@<remote_ip_address>:/ /home/<host_user>/mntpoint/ -o transform_symlinks -o allow_other

কমান্ড, বিশেষত <placeholders>, নির্দিষ্ট পরিবেশের সাথে মানিয়ে নেওয়া হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.