কীভাবে শর্তের সাথে এসএসএইচ কাজ করতে পারে?


8

ifফাইলগুলি গণনা করতে এবং সর্বশেষ তিনটি ফাইল ব্যতীত সমস্ত মুছতে আমার কাছে একটি বিবৃতি রয়েছে। তবে আমি এই কমান্ডটি দূর থেকে চালাতে চাই। আমি কীভাবে sshএকটি ifশর্তের সাথে একত্রিত করতে পারি ?

আমি এটি চেষ্টা করেছিলাম কিন্তু কোন সাফল্য পাইনি।

#!/bin/bash

ssh -t  test@192.168.94.139 "cd /var/www/test.com/backup ;

if [ $(ls  | wc -l) -lt 3  ]
then
    echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
    echo "deleted"
fi"

আমি যে ত্রুটি পেয়েছি:

ls: * .tgz অ্যাক্সেস করতে পারবেন না: এই জাতীয় কোনও ফাইল বা ডিরেক্টরি নেই


তাহলে আমি কীভাবে এটি কাস্টমাইজ করব?
জানিথ

@ user68186 এটি কেন? কমান্ডটি উদ্ধৃতিতে রয়েছে।
অরবিট

2
$( )কমান্ডের অংশ স্থানীয় শেল দ্বারা সঞ্চালিত আগে এটা এমনকি আরম্ভ হয় sshকমান্ড। এটি সত্যই উভয় যখন $( )একা দাঁড়িয়ে পাশাপাশি পাশাপাশি এটি দ্বারা আবদ্ধ থাকে "। তবে এর $( )ভিতরে থাকলে 'এটি স্থানীয় শেল দ্বারা কার্যকর করা হবে না।
ক্যাস্পার্ড

উত্তর:


3

দ্রষ্টব্য: এখানে প্রশ্নের দুটি স্তর রয়েছে। একটি হ'ল আমি এসএসএইচ এর মাধ্যমে অ্যাক্সেসযোগ্য দূরবর্তী সার্ভারে একটি তুচ্ছ-তুচ্ছ কাজ সম্পাদন করতে চাই '। অন্যটি হ'ল আমি একটি কমান্ডের কাছে একটি জটিল স্ট্রিং দেওয়ার চেষ্টা করছি এবং যুক্তিটি আমার উদ্দেশ্য থেকে পৃথক হয়ে গেছে ' আমি উচ্চ-স্তরের প্রশ্নের সমাধানের জন্য ব্যবহৃত পদ্ধতির "সঠিক" (সুবিধাজনক, অ-ত্রুটি-প্রবণ, সুরক্ষিত ইত্যাদি) কিনা তা আলোচনা না করেই নিম্ন-স্তরের প্রশ্নের উত্তর দিচ্ছি। অন্যান্য উত্তর এবং মন্তব্য দ্বারা ইঙ্গিত হিসাবে, সম্ভবত এটি সম্ভবত না।

আপনার কমান্ড লাইন বেশিরভাগই সঠিক; আপনাকে কেবল উদ্ধৃতিটি কিছুটা পরিবর্তন করতে হবে।

মূল সমস্যাটি হ'ল ডাবল-কোটেড স্ট্রিংগুলি আপনার স্থানীয় শেল দ্বারা প্রসারিত হয়, এবং সুতরাং $(...)অংশগুলি আপনার স্থানীয় সিস্টেমে মূল্যায়ন করা হবে। এগুলি দূরবর্তী সিস্টেমে পাস করার জন্য, আপনাকে স্ক্রিপ্টটি একক উদ্ধৃতিতে আবদ্ধ করতে হবে।

আপনার কিছু এম্বেডেড উদ্ধৃতি চিহ্ন রয়েছে। আপনার মূল স্ক্রিপ্টে, দু'জনের পক্ষে যুক্তি রয়েছে echo; আপনি যদি বাইরের উক্তিটি একক উদ্ধৃতিতে পরিবর্তন করেন তবে এটি অ্যাজ স্ক্রিপ্ট হবে। এই কার্যকরভাবে কোটেশন চিহ্নগুলি বাদ দেওয়া হয়েছে যার ফলে এটিগুলি বিরক্ত হয় না echo, তবে এটি অর্ক স্ক্রিপ্টকে বিশৃঙ্খলা করবে, কারণ বৃহত্তর চিহ্নটি আউটপুট পুনঃনির্দেশে পরিণত হবে। সুতরাং আপনি বাহ্যিক উদ্ধৃতি চিহ্নগুলি একক উদ্ধৃতিতে পরিবর্তন করার পরে সেগুলি ডাবল কোটে পরিবর্তন করুন।

এই উদ্ধৃতি স্থির সঙ্গে আপনার স্ক্রিপ্ট। স্ক্রিপ্টে অন্যান্য সমস্যা থাকতে পারে, আমি কেবল বাক্য গঠন ঠিক করেছি fixed

#!/bin/bash

ssh -t  test@192.168.94.139 'cd /var/www/test.com/backup ;

if [ $(ls  | wc -l) -lt 3  ]
then
  echo "Less"
else [ $(ls -t *.tgz|awk "NR >3"|xargs rm -f) ]
  echo "deleted"
fi'

আমি /var/www/test.com/backup"BACKUPDEST" নামক একটি ভেরিয়েবলের মধ্যে নিয়োগ দিতে চাই এবং cd $BACKUPDESTআপনি কীভাবে এটি করতে পারেন আমাকে বলতে পারেন?
জানিথ

1
আপনি কোথায় মান নির্ধারণ করবেন BACKUPDEST? যদি এটি দূরবর্তী দিক থেকে ঘটে থাকে, তবে সাধারণত স্ক্রিপ্টে এটি অন্তর্ভুক্ত করুন। আপনি যদি এটি স্থানীয়ভাবে সেট করতে চান (উদাহরণস্বরূপ স্থানীয় স্ক্রিপ্টে এটি গণনা করুন, বা কমান্ড লাইন আর্গুমেন্ট হিসাবে এটি পাস করুন), আপনি প্রথম লাইনটি উদাহরণস্বরূপ পরিবর্তন করতে পারেন "cd $BACKUPDEST"' ;- শেলটি দ্বিগুণ-উদ্ধৃত অংশকে প্রসারিত করে, একক-উদ্ধৃত রাখে অংশ অক্ষত, দু'জনকে সম্মতি জানায় এবং ফলাফলটিকে শেষ যুক্তি হিসাবে পাস করে ssh
pt314

ওহ, "cd '$BACKUPDEST'"' ;সেই পরিবর্তনশীল পথে যদি কিছু অদ্ভুততা থাকে (উদাহরণস্বরূপ একটি স্থান) থাকে তা তৈরি করুন make আবার: কেবল বলছি যে এটি এইভাবে করা যায়, এটি নয় যে এটি এইভাবে করা উচিত।
pt314

10

হ্যাঁ আপনি এর মাধ্যমে জটিল স্ক্রিপ্টগুলি এক্সক্সেট করতে পারেন ssh

#!/bin/bash -e

ssh_cmd="$(cat <<-EOF
    cd /var/www/test.com/backup;

    if [ \$(ls  | wc -l) -lt 3  ]; then
        echo "less"
    elif [ \$(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
        echo "deleted"
    else
        echo "something else"
    fi
EOF
)"

ssh -t test@192.168.94.139 "$ssh_cmd"

এই উদাহরণটি কমান্ড স্ট্রিং উত্পন্ন করতে এখানে ব্যাশ ডকুমেন্ট ব্যবহার করে । যে কোনও ক্ষেত্রে, ssh এর মাধ্যমে স্ক্রিপ্টগুলি পাস করা ত্রুটি প্রবণ, কারণ ভেরিয়েবলগুলি উদ্ধৃত করা এবং পলায়ন করা কঠিন (কমান্ডগুলির আগে ব্যাকস্ল্যাশটিকে মনে রাখবেন)। যদি স্ক্রিপ্টটি খুব জটিল হয়ে যায় scpতবে এটির মাধ্যমে অনুলিপি করা এবং তারপরে লক্ষ্য হোস্টে এটি কার্যকর করা ভাল ।

আমি আপনার স্ক্রিপ্টটি ঠিক করার চেষ্টা করিনি , তবে দূরবর্তী হোস্টে গণনা এবং মোছা কীভাবে কাজ করতে পারে তার একটি উদাহরণ এখানে:

#!/bin/bash -e

tmp_dir="$(mktemp -d)"

ssh_cmd="$(cat <<-EOF
    cd "$tmp_dir"

    cnt_tgz=(\$(find . -type f -name "*.tgz"))
    if [[ \${#cnt_tgz[@]} -lt 3 ]]; then
        echo "less"
    else
        rm "\${cnt_tgz[@]}"
        echo "deleted"
    fi
EOF
)"

touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"

ls -t *.tgzকাজ করবে না, যেহেতু globbing শুধুমাত্র স্থানীয় সিস্টেমে ঘটছে। এছাড়াও ব্যবহার lsবেড়ে চলেছে ফাইলের জন্য একটি ভাল ধারণা, যেহেতু এটি মত এন্ট্রি ফেরৎ নয় ., ..ও ডিরেক্টরিগুলি।


আমি কিছু ত্রুটি পেয়েছি। syntax error near unexpected token elif',elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
জানিথ

;মুষ্টিতে ইফ-স্টেটমেন্টটিতে একটি অনুপস্থিত ছিল । তবে আমি আপনাকে স্ক্রিপ্ট ঠিক করিনি! আরও অনেক ইস্যু রয়েছে যেমনls *.tgz
সাইমন সুডলার

1
"Ls -t * .tgz কাজ করবে না, যেহেতু গ্লোব্বিং কেবল স্থানীয় সিস্টেমে ঘটছে।" - আপনি সঠিকভাবে এড়াতে পারলে এটি দূরবর্তী সিস্টেমে ঘটবে। আসল সংস্করণটি $(...)একটি ডাবল-কোটড স্ট্রিংয়ের ভিতরে উলঙ্গ ছিল , তাই স্থানীয় শেল এটি মূল্যায়ন করে। \$(...)আপনি যেমন প্রথম উদাহরণটিতে যেমন দেখিয়েছিলেন তেমন এড়িয়ে চলে যাওয়া বা পুরো স্ক্রিপ্টের চারপাশে একক উদ্ধৃতি ব্যবহার করে স্থানীয় শেলটি এটি প্রসারিত হতে বাধা দেয়, তাই এটি দূরবর্তী সিস্টেমে প্রেরণ হয়ে যায়, এটি রিমোট শেল দ্বারা প্রসারিত হয় এবং স্ক্রিপ্টটি কাজ করে উদ্দেশ্যে.
pt314

এই পরিস্থিতি যেখানে আমি করে ধরনের অত্যন্ত একক পরিবর্তে কোট একটি এখানে ডকুমেন্ট ব্যবহার সুপারিশ। আপনার কিছু ভেরিয়েবল আপনি সন্নিবেশ করতে চান তা printfসত্ত্বেও , আপনি একক-উদ্ধৃত স্ট্রিংটি ব্যবহার করে এবং ভেরিয়েবলগুলি প্রসারিত করার চেয়ে আরও ভাল that's এটি এখনও সমস্ত শেল ভেরিয়েবলগুলি ছড়িয়ে দেওয়ার চেষ্টা করার চেয়ে পরিচালনা করা আরও সহজ হতে পারে। এছাড়াও, এটি catকেবল এখানে ভেরিয়েবলের দস্তাবেজ ক্যাপচার করার জন্য ব্যবহার করা প্রয়োজন এড়ানো হবে !
ড্যানিয়েল প্রাইডেন

4

আমি মনে করি এই জটিল জটিল উদ্ধৃতি স্টাফ এটি ব্যবহার না করে পরিবর্তে একটি স্ক্রিপ্ট ব্যবহার করার পক্ষে যথেষ্ট প্রমাণ। আপনি যদি একাধিক sshসংযোগ এড়াতে চান তবে স্ক্রিপ্টটি অন্য হোস্টের কাছে পাইপ করুন এবং এটি একটি কমান্ডের মধ্যে চালাতে দিন:

স্থানীয় ফাইল, বলুন myscript.sh:

cd /var/www/test.com/backup;

if [ $(ls  | wc -l) -lt 3  ]; then
    echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
    echo "deleted"
else
    echo "something else"
fi

তারপর:

cat myscript.sh | \
    ssh -t test@192.168.94.139 \
    "cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"

বা ( বিড়ালের অকেজো ব্যবহার এড়ানো ):

ssh -t test@192.168.94.139 \
    "cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh" \
    < myscript.sh

এটি স্থানীয় স্ক্রিপ্টটিকে myscript.shদূরবর্তী দিক থেকে পাইপ করে যেখানে এটি একটি (অস্থায়ী) ফাইলে পুনঃনির্দেশিত হয় /tmp/ms.sh, কার্যকর হয় এবং শেষ পর্যন্ত সরানো হয়।

দ্রষ্টব্য: আমি ত্রুটিগুলির জন্য মূল স্ক্রিপ্টটি চেক করি নি তবে কেবল ধারণাটি দেখাতে চেয়েছিলাম। কোনও ত্রুটিযুক্ত প্রবণ উদ্ধৃতি আবশ্যক নয় এবং স্ক্রিপ্টের সমস্ত কমান্ড দূরবর্তী দিকে কার্যকর করা হবে।


কোনও অস্থায়ী ফাইলে স্ক্রিপ্টটি সংরক্ষণ করার দরকার নেই, কেবল এটি একটি উপযুক্ত শেলের মধ্যে পাইপ করুন, যেমন ssh user@host bash <myscript.sh
pt314

2
তবে মনে রাখবেন যে পুনর্নির্দেশটি কেবল তখনই কাজ করে যখন স্ক্রিপ্ট নিজেই স্ট্যান্ডার্ড ইনপুট থেকে পড়ার চেষ্টা করে না।
চিপনার


হ্যাঁ, পুনঃনির্দেশের সীমাবদ্ধতা রয়েছে। এটি পূর্বাভাসযুক্ত নামযুক্ত অস্থায়ী ফাইল লেখার (এবং তারপরে কার্যকর করা) যুক্ত অনেকগুলি সুরক্ষা বিষয়গুলি এড়িয়ে যায়। আপনি যদি কোনও অস্থায়ী স্ক্রিপ্ট ব্যবহার করেন (পছন্দ অনুযায়ী বা প্রয়োজনীয়তার দ্বারা), এটি ব্যবহার করে তৈরি করুন mktempবা অনুরূপ নিরাপদ কিছু।
pt314

3

আমি স্ক্রিপ্টটি দূরবর্তী উদাহরণে স্থাপন করতে এবং এটি কেবল এসএসএসের মাধ্যমে কার্যকর করতে পছন্দ করব তবে আপনি যেভাবে চান এটি কীভাবে এটি করা যায় তা এখানে আমার পরামর্শ:

#!/bin/bash

HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'

COMMAND1="ssh \"$HOST\" 'ls \"$REMOTE_PATH\" | wc -l'"
COMMAND2="ssh \"$HOST\" 'ls -t \"$REMOTE_PATH\"/*.tgz'"
COMMAND3="xargs ssh \"$HOST\" rm -rf"

if [[ $(eval "$COMMAND1") -le 3 ]]
then
    echo "Less"
else
    eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi

মন্তব্য:

  • শর্তসাপেক্ষ এক্সপ্রেশন -ltদ্বারা প্রতিস্থাপিত হয় -le
  • eval - যুক্তি যুক্ত করে কমান্ডটি তৈরি করুন।
  • আমি নিশ্চিত নই যে আমাদের সত্যিকারের অভিব্যক্তিটির \"মধ্যে এই অতিরিক্ত উদ্ধৃতিগুলি দরকার $COMMAND{1..3}, তবে আমি সেগুলি যুক্ত করার সিদ্ধান্ত নিয়েছি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.