التحقق من رموز إرجاع بروتوكول نقل الملفات من البرنامج النصي Unix

StackOverflow https://stackoverflow.com/questions/140012

  •  02-07-2019
  •  | 
  •  

سؤال

أقوم حاليًا بإنشاء مهمة بين عشية وضحاها تستدعي برنامج نصي Unix والذي بدوره يقوم بإنشاء ملف ونقله باستخدام ftp.أود التحقق من جميع رموز الإرجاع الممكنة.صفحة الرجل ل ftp لا يسرد رموز الإرجاع.هل يعرف أحد أين يمكن العثور على القائمة؟أي شخص لديه خبرة في هذا؟لدينا نصوص برمجية أخرى تعمل على معالجة سلاسل إرجاع معينة في السجل، وترسل بريدًا إلكترونيًا عند حدوث خطأ.ومع ذلك، غالبًا ما تفوتهم رموز غير متوقعة.ثم أقوم بوضع السبب في السجل والبريد الإلكتروني.

هل كانت مفيدة؟

المحلول

ال ftp لا يُرجع الأمر أي شيء آخر غير الصفر في معظم التطبيقات التي صادفتها.

من الأفضل بكثير معالجة الرموز المكونة من ثلاثة أرقام في السجل - وإذا كنت ترسل ملفًا ثنائيًا، فيمكنك التحقق من صحة وحدات البايت المرسلة.

تسمى الرموز المكونة من ثلاثة أرقام "رموز السلسلة" ويمكن العثور على قائمة بها هنا

نصائح أخرى

لقد كتبت برنامجًا نصيًا لنقل ملف واحد فقط في كل مرة واستخدام هذا البرنامج النصي grep للتحقق من 226 Transfer complete رسالة.فإذا وجدها، grep يعود 0.

ftp -niv < "$2"_ftp.tmp | grep "^226 "

تحميل هذا com.ncftp طَرد.لأنه يأتي مع ncftpget و com.ncftpput والتي ستحاول كل منها تحميل/تنزيل ملف واحد، والعودة برمز خطأ وصفي في حالة وجود مشكلة.راجع قسم "التشخيص" في صفحة الرجل.

أعتقد أنه من الأسهل تشغيل بروتوكول نقل الملفات والتحقق من رمز الخروج الخاص ببروتوكول نقل الملفات إذا حدث خطأ ما.

فعلت هذا مثل المثال أدناه:

# ...
ftp -i -n $HOST 2>&1 1> $FTPLOG << EOF
quote USER $USER
quote PASS $PASSWD
cd $RFOLDER
binary
put $FOLDER/$FILE.sql.Z $FILE.sql.Z
bye
EOF

# Check the ftp util exit code (0 is ok, every else means an error occurred!)
EXITFTP=$?
if test $EXITFTP -ne 0; then echo "$D ERROR FTP" >> $LOG; exit 3; fi
if (grep "^Not connected." $FTPLOG); then echo "$D ERROR FTP CONNECT" >> $LOG; fi 
if (grep "No such file" $FTPLOG); then echo "$D ERROR FTP NO SUCH FILE" >> $LOG; fi 
if (grep "access denied" $FTPLOG ); then echo "$D ERROR FTP ACCESS DENIED" >> $LOG; fi
if (grep "^Please login" $FTPLOG ); then echo "$D ERROR FTP LOGIN" >> $LOG; fi

يحرر: للقبض على الأخطاء أقوم بإخراج أمر ftp.لكنه في الحقيقة ليس الحل الأفضل.

لا أعرف مدى معرفتك بلغة البرمجة النصية مثل Perl أو Python أو Ruby.لديهم جميعًا وحدة FTP التي يمكنك استخدامها.يمكّنك هذا من التحقق من الأخطاء بعد كل أمر.هنا مثال في بيرل:

#!/usr/bin/perl -w
use Net::FTP;
$ftp = Net::FTP->new("example.net") or die "Cannot connect to example.net: $@";
$ftp->login("username", "password") or die "Cannot login ", $ftp->message;
$ftp->cwd("/pub") or die "Cannot change working directory ", $ftp->message;
$ftp->binary;
$ftp->put("foo.bar") or die "Failed to upload ", $ftp->message;
$ftp->quit;

لكي يعمل هذا المنطق، يحتاج المستخدم إلى إعادة توجيه STDERR أيضًا من أمر ftp على النحو التالي

ftp -i -n $HOST >$FTPLOG 2>&1 << EOF

سيتم دائمًا تعيين الأمر أدناه 0 (نجاح) لأن أمر ftp لن يُرجع النجاح أو الفشل.لذا لا ينبغي للمستخدم أن يعتمد عليه

EXITFTP=$?

أعرف الإجابة الضعيفة، ولكن ماذا عن الحصول على مصادر بروتوكول نقل الملفات وانظر بنفسك

يعجبني الحل الذي قدمه Anurag، بالنسبة لمشكلة نقل البايتات، قمت بتوسيع الأمر باستخدام grep -v "bytes"

أي

grep "^530" ftp_out2.txt | بايت -v "بايت"

-بدلاً من 530 يمكنك استخدام جميع رموز الأخطاء كما فعل أنوراغ.

لقد قلت أنك تريد نقل الملف إلى FTP هناك، لكنك لم تذكر ما إذا كان عميل BSD FTP العادي هو الطريقة الوحيدة التي تريد نقل الملف إليها أم لا.لا يمنحك BSD FTP رمز إرجاع لحالات الخطأ التي تتطلب كل هذا التحليل، ولكن هناك سلسلة كاملة من برامج Unix الأخرى التي يمكن استخدامها لنقل الملفات عن طريق FTP إذا قمت أنت أو المسؤول بتثبيتها.سأقدم لك بعض الأمثلة على طرق نقل ملف عبر FTP مع الاستمرار في اكتشاف جميع حالات الخطأ باستخدام كميات قليلة من التعليمات البرمجية.

FTPUSER هو اسم تسجيل دخول مستخدم ftp الخاص بك

FTPPASS هي كلمة مرور بروتوكول نقل الملفات الخاصة بك

FILE هو الملف المحلي الذي تريد تحميله بدون أي معلومات مسار (على سبيل المثال file1.txt، وليس /whatever/file1.txt أو أيًا كان/file1.txt)

FTPHOST هو الجهاز البعيد الذي تريد FTP إليه

يعد REMOTEDIR مسارًا مطلقًا للموقع الموجود على الجهاز البعيد الذي تريد التحميل إليه

فيما يلي الأمثلة:

حليقة - المستخدم $FTPUSER:$FTPASS -T $FILE ftp://$FTPHOST/%2f$REMOTEDIR

تحميل ftp --المضيف $FTPHOST --المستخدم $FTPUSER --كلمة المرور $FTPPASS --as $REMOTEDIR/$FILE $FILE

tnftp -u ftp://$FTPUSER:$FTPASS@$FTPHOST/%2f$REMOTEDIR/$FILE $FILE

wput $FILE ftp://$FTPUSER:$FTPPASS@$FTPHOST/%2f$REMOTEDIR/$FILE

ستعيد جميع هذه البرامج رمز خروج غير صفري في حالة حدوث أي خطأ على الإطلاق، بالإضافة إلى نص يشير إلى ما فشل.يمكنك اختبار ذلك ثم القيام بما تريد بالمخرجات، وتسجيلها، وإرسالها بالبريد الإلكتروني، وما إلى ذلك كما يحلو لك.

يرجى ملاحظة ما يلي مع ذلك:

  1. يتم استخدام "%2f" في عناوين URL للإشارة إلى أن المسار التالي هو مسار مطلق على الجهاز البعيد.ومع ذلك، إذا قام خادم FTP الخاص بك باستدعاءك، فلن تتمكن من تجاوز هذا.

  2. للأوامر المذكورة أعلاه والتي تستخدم عنوان URL الفعلي (بروتوكول نقل الملفات: // الخ) إلى الخادم الذي يتضمن المستخدم وكلمة المرور المضمنين فيه، يجب أن يكون اسم المستخدم وكلمة المرور مشفرين بعنوان URL إذا كان يحتوي على أحرف خاصة.

  3. في بعض الحالات، يمكنك أن تكون مرنًا حيث يكون الدليل البعيد مطلقًا والملف المحلي هو مجرد اسم ملف عادي بمجرد أن تصبح على دراية بصيغة كل برنامج.قد يتعين عليك فقط إضافة متغير بيئة الدليل المحلي أو مجرد ترميز كل شيء.

  4. إذا كنت حقًا، يجب عليك بالتأكيد استخدام عميل FTP عادي، إحدى الطرق التي يمكنك من خلالها اختبار الفشل هي من خلال، داخل البرنامج النصي الخاص بك، بما في ذلك أولاً أمر يضع الملف، متبوعًا بأمر آخر يقوم بإجراء GET لنفس الملف ويعيده تحت عنوان مختلف. اسم.بعد خروج FTP، ما عليك سوى اختبار وجود الملف الذي تم تنزيله في برنامج Shell النصي الخاص بك، أو حتى جمعه مقابل الملف الأصلي للتأكد من نقله بشكل صحيح.نعم، هذا أمر سيء، ولكن في رأيي، من الأفضل أن يكون لديك رمز يسهل قراءته بدلاً من إجراء الكثير من التحليلات لكل حالة خطأ محتملة.BSD FTP ليس بهذه الروعة.

هذا ما ذهبت إليه أخيرًا.شكرا لجميع التعليمات.كل الإجابات تساعدني في الاتجاه الصحيح.قد يكون الأمر مبالغًا فيه قليلًا، التحقق من النتيجة والسجل، لكن يجب أن يغطي جميع القواعد.

echo "open ftp_ip
pwd
binary    
lcd /out
cd /in
mput datafile.csv
quit"|ftp -iv > ftpreturn.log

ftpresult=$?

bytesindatafile=`wc -c datafile.csv | cut -d " " -f 1`    
bytestransferred=`grep -e '^[0-9]* bytes sent' ftpreturn.log | cut -d " " -f 1`    
ftptransfercomplete=`grep -e '226 ' ftpreturn.log | cut -d " " -f 1`

echo "-- FTP result code: $ftpresult" >> ftpreturn.log
echo "-- bytes in datafile: $bytesindatafile bytes" >> ftpreturn.log
echo "-- bytes transferred: $bytestransferred bytes sent" >> ftpreturn.log

if [ "$ftpresult" != "0" ] || [ "$bytestransferred" != "$bytesindatafile" ] || ["$ftptransfercomplete" != "226" ]    
then    
  echo "-- *abend* FTP Error occurred" >> ftpreturn.log    
  mailx -s 'FTP error' `cat email.lst` < ftpreturn.log
else    
  echo "-- file sent via ftp successfully" >> ftpreturn.log    
fi

لماذا لا تقوم فقط بتخزين كل مخرجات الأمر في ملف سجل، ثم تحقق من رمز الإرجاع من الأمر، وإذا لم يكن 0، فأرسل ملف السجل في البريد الإلكتروني؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top