নিরাপদে নিরাপদে- find -exec sh -c` ব্যবহার করা সম্ভব?


29

আমি কয়েকটি ফাইলগুলিতে ব্যবহার findকরার চেষ্টা করছি echo 0তবে দৃশ্যত এটি কেবল এটির সাথে কাজ করে sh -c:

find /proc/sys/net/ipv6 -name accept_ra -exec sh -c 'echo 0 > {}' \;

তবে এর সাথে ব্যবহার sh -cকরা find -execআমাকে খুব অস্বস্তি বোধ করে কারণ আমার উদ্ধৃতিতে সমস্যাগুলির সন্দেহ। আমি এটি দিয়ে কিছুটা ফিড করেছিলাম এবং স্পষ্টতই আমার সন্দেহগুলি ন্যায়সঙ্গত হয়েছিল:

  • আমার পরীক্ষার সেটআপ:

    martin@dogmeat ~ % cd findtest 
    martin@dogmeat ~/findtest % echo one > file\ with\ spaces
    martin@dogmeat ~/findtest % echo two > file\ with\ \'single\ quotes\'
    martin@dogmeat ~/findtest % echo three > file\ with\ \"double\ quotes\"
    martin@dogmeat ~/findtest % ll
    insgesamt 12K
    -rw-rw-r-- 1 martin martin 6 Sep 17 12:01 file with "double quotes"
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with 'single quotes'
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with spaces
    
  • ব্যবহার find -execব্যতীত sh -cসমস্যাগুলি কাজ করে বলে মনে হচ্ছে - এখানে কোনও উদ্ধৃতি আবশ্যক নয়:

    martin@dogmeat ~ % find findtest -type f -exec cat {} \;
    one
    two
    three
    
  • তবে যখন আমি ব্যবহার করছি তখন sh -c {}মনে হচ্ছে কিছু ধরণের উদ্ধৃতি প্রয়োজন:

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat {}' \;
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: spaces: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: single quotes: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: double quotes: No such file or directory
    
  • ডাবল উদ্ধৃতিগুলি যতক্ষণ কাজ করে না যতক্ষণ না কোনও ফাইলের নামের ডাবল উক্তি থাকে:

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat "{}"' \;
    one
    two
    cat: findtest/file with double: No such file or directory
    cat: quotes: No such file or directory
    
  • একক উদ্ধৃতি ততক্ষণ কাজ করে যতক্ষণ না কোনও ফাইলের নামের একক উদ্ধৃতি না থাকে:

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c "cat '{}'" \;
    one
    cat: findtest/file with single: No such file or directory
    cat: quotes: No such file or directory
    three
    

আমি এমন কোনও সমাধান খুঁজে পাইনি যা সব ক্ষেত্রে কার্যকর হয়। ই অনেক কিছু আমার দেখা করছি, বা ব্যবহার করছে sh -cfind -execমজ্জাগতভাবে অনিরাপদ?

উত্তর:


40

{}শেল কোড এম্বেড কখনও ! এটি একটি কমান্ড ইনজেকশন দুর্বলতা তৈরি করে। নোট যে জন্য cat "{}"এটা, তাই না মাত্র "অক্ষর, \, `, $একটি সমস্যা হয় (উদাহরণস্বরূপ নামক একটি ফাইল বিবেচনা ./$(reboot)/accept_ra)।

(উপায় দ্বারা, কিছু findবাস্তবায়নের আপনি যে কাজ করতে দিন হবে না, এবং POSIX আচরণ ছেড়ে অনির্দিষ্ট যখন {}একটি যুক্তি তার নিজের উপর নয় find)

এখানে, আপনি ফাইলের নামগুলি পৃথক আর্গুমেন্ট হিসাবে sh( কোড আর্গুমেন্টে নয়) এবং shইনজল স্ক্রিপ্ট ( কোড আর্গুমেন্ট) অবস্থানিক পরামিতি ব্যবহার করে তাদের উল্লেখ করতে চান:

find . -name accept_ra -exec sh -c 'echo 0 > "$1"' sh {} \;

অথবা, shপ্রতি ফাইলের মধ্যে একটি চালনা এড়াতে :

find . -name accept_ra -exec sh -c 'for file do
  echo 0 > "$file"; done' sh {} +

একই ক্ষেত্রে প্রযোজ্য xargs -I{}বা zshএর zargs -I{}। লিখবেন না:

<list.txt xargs -I {} sh -c 'cmd> {}'

যা findউপরের মত একইভাবে কমান্ড ইনজেকশন দুর্বলতা হতে পারে তবে:

<list.txt xargs sh -c 'for file do cmd > "$file"; done' sh

যার মধ্যে shপ্রতি ফাইলের জন্য একটি চালানো এড়ানো এবং list.txtকোনও ফাইল না থাকাতে ত্রুটি রয়েছে।

সঙ্গে zsh'র zargs, আপনি সম্ভবত invoking বদলে একটি ফাংশন ব্যবহার করতে চান চাই sh -c:

do-it() cmd > $1
zargs ./*.txt -- do-it

নোট করুন যে উপরের দ্বিতীয়টির shউপরের সমস্ত উদাহরণে ইনলাইন স্ক্রিপ্টটি যায় $0। আপনি সেখানে প্রাসঙ্গিক কিছু (যেমন ব্যবহার করা উচিত shবা find-sh), না কিছু পছন্দ _, -, --বা খালি স্ট্রিং, মান যেমন $0শেল এর ত্রুটিসূচক বার্তাগুলি ব্যবহার করা হয়:

$ find . -name accept_ra -exec sh -c 'echo 0 > "$1"' inline-sh {} \;
inline-sh: ./accept_ra: Permission denied

জিএনইউ parallelআলাদাভাবে কাজ করে। এটি দিয়ে, আপনি কি না ব্যবহার করতে চান sh -cযেমন parallelপ্রতিস্থাপন করতে ইতিমধ্যেই চেষ্টা শেল চালানোর নেই {}যুক্তি শেল জন্য সঠিক বাক্য গঠন উদ্ধৃত সঙ্গে

<list.txt PARALLEL_SHELL=sh parallel 'cmd > {}'

না না দ্বিতীয় sh, স্থানধারক কিছু হবে বলে মনে হয় এটা খুব কাজ করে দ্বারা প্রতিস্থাপিত _উদাহরণস্বরূপ - আপনি ব্যাশ অভ্যন্তরীণ কল করতে চান খুব দরকারী: find /tmp -name 'fil*' -exec bash -c 'printf "%q\n" "$1"' _ {} \;। তবে কেউ কি জানেন যে এটি কোথায় নথিভুক্ত?
ফ্লোরিয়ান ফিদা

1
@ ফ্লোরিয়ানফিডা শেলের প্রথম যুক্তিটি হয়ে যায় $0(সাধারণত শেলের নাম You আপনাকে এই দৃশ্যে এড়িয়ে চলতে হবে যাতে এটি আপনার স্বাভাবিক অবস্থানের কোনও যুক্তি খায় না for ডকুমেন্টেশনের মধ্যে এটি -cউল্লেখ করা হয়েছে
এটান রিজনার


1
@ পিএফকে, এটি argv[0]এখানে নেই, এটি কেবল $0স্ক্রিপ্টের। সোভেনের পৃষ্ঠাটি এখানে সঠিক নয়, rএটি শেলটিকে একটি সীমাবদ্ধ মোডে প্রবেশ zshকরবে না যতক্ষণ না বলতে পারে এবং এর ভিত্তিতে মোড পরিবর্তন করবে না $0(exec -a rksh ksh -c 'cd /')একটি সীমাবদ্ধ চালাবে ksh, তবে নয় ksh -c 'cd /' rksh)।
স্টাফেন চেজেলাস

1
স্টাফেন, যদি আপনি কিছু মনে করেন না, তবে আপনার কোনও উত্তর আছে যা "শেল কোডটিতে এম্বেড করবে না" কেন? আমি যদিও অধীনে আপনার সব উত্তর গিয়েছিলাম খোঁজ কিন্তু এক খুঁজে পাইনি যদিও আমি শপথ করে বলতে পারি আমি কিছু কাপড় দেখেছি যে আপনি এই বিষয় সম্পর্কে লেখা ছিল কিন্তু যদি এটা একটা উত্তর, চ্যাট অথবা compunix মত অন্য কোনো সাইটে একটি মন্তব্যে ছিল প্রত্যাহার করতে পারবেন না ... যদি / যখন আপনি সময় আছে, আপনি "কখনও এম্বেড {}" পক্ষ থেকে বিস্তৃত কিছু মনে করবে বা আপনি মনে করেন আমরা ডেডিকেটেড প্রশ্ন যেমন থাকা উচিত না "ব্যবহার নিরাপত্তা প্রভাব findসঙ্গে -exec sh -cএবং এমবেডিং {}শেল কোডে" ?
don_crissti
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.