اذهب إلى المحتوى

لوحة المتصدرين

  1. محمود سعداوي2

    محمود سعداوي2

    الأعضاء


    • نقاط

      5

    • المساهمات

      604


  2. محمد عاطف17

    محمد عاطف17

    الأعضاء


    • نقاط

      4

    • المساهمات

      3124


  3. ايمن ميلاد

    ايمن ميلاد

    الأعضاء


    • نقاط

      3

    • المساهمات

      247


  4. Mustafa Mahmoud7

    Mustafa Mahmoud7

    الأعضاء


    • نقاط

      2

    • المساهمات

      676


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 08/03/24 في كل الموقع

  1. السلام عليكم. أرجو مساعدتي في التحقق من البيانات بواسطة cookie و jwt في مشروع Nextjs 14. تظهر لي رسالة الخطأ التالية { "message": "Not authorized, no token" } للتوضيح: في البداية قمت بتوليد token و cookie utils/generateToken import jwt from 'jsonwebtoken' const generateToken = (id) => { const token = jwt.sign({ userId: id }, process.env.JWT_SECRET, { expiresIn: '1d' }); return token; } const setTokenCookie = (response, token) => { response.cookies.set('token', token, { httpOnly: true, secure: process.env.NODE_ENV !== 'development', sameSite: 'strict', maxAge: 60*60*24 }); } export { generateToken, setTokenCookie }; ثم قمت بإنشاء الحساب وتسجيل الدخول (سوف أعرض تسجيل الدخول لأنهما مشابهين كثيرا) app/api/auth/login/route.js import connectDB from "@/config/connectDB"; import User from "@/models/User"; import { generateToken, setTokenCookie } from "@/utils/generateToken"; import bcrypt from "bcryptjs"; import { NextResponse } from "next/server"; /** * Method: POST * route : /api/auth/login */ export const POST = async (request) => { await connectDB(); try { const { email, password } = await request.json(); const user = await User.findOne({ email }); const isMatch = await bcrypt.compare(password, user.password) if (!user || !isMatch) { return new NextResponse("Invalid Credentials", { status: 400 }) } if (user) { const token = generateToken(user._id); const response = new NextResponse( JSON.stringify({ user: user.email }), { status: 200 } ); setTokenCookie(response, token); return response; } else { return new NextResponse("Failed to create user", { status: 500 }); } } catch (error) { console.log(error); return new Response("Something went wrong => Register User", { status: 500, }); } }; ثم قمت بتحديد الوسائط middlewares/protect.js import User from "@/models/User"; import { cookies } from "next/headers"; const protect = async (request) => { const cookieStore = cookies() const token = cookieStore.get('jwt')?.value; if (!token) { throw new Error('Not authorized, no token'); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.userId) if (!user) { throw new Error('Not authorized, user not found'); } return user; } catch (error) { console.error(error); throw new Error('Not authorized, token failed'); } }; export default protect; في النهاية لتجربة التحقق قمت ب: app/api/auth/me/route.js import connectDB from "@/config/connectDB" import protect from "@/middleware/protect" import User from "@/models/User" import { NextResponse } from "next/server" /** * Test If Route Is Protected */ export const GET = async (request) => { await connectDB() try { const user = await protect(request) const me = await User.findById(user._id ) return NextResponse.json(me, { status: 200 }) } catch (error) { return NextResponse.json({ message: error.message }, { status: 401 }); } } الرجاء مساعدتي في تحديد سبب فشل التحقق من البيانات. شكرا.
    4 نقاط
  2. انا جديد بالبرمجة، كيف اجعل النتائج التي تظهر في ال console توضع في مكان آخر أسميته code.py
    2 نقاط
  3. عند تسجيل مستخدم جديد في موقعي يتم ارسال بريد التحقق الى البريد غير المرغوب فيه كيف جعله يرسل بريد التحقق الى البريد الوارد <!DOCTYPE html> <html lang="ar"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>التسجيل</title> <link rel="stylesheet" href="styles.css"> </head> <body> <form action="register.php" method="POST"> <h2>التسجيل</h2> <label for="username">اسم المستخدم:</label> <input type="text" id="username" name="username" required> <label for="email">البريد الإلكتروني:</label> <input type="email" id="email" name="email" required> <label for="password">كلمة المرور:</label> <input type="password" id="password" name="password" required> <button type="submit">تسجيل</button> </form> <?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if ($_SERVER['REQUEST_METHOD'] == 'POST') { require 'config.php'; $username = base64_encode($_POST['username']); $email = $_POST['email']; $password = base64_encode(password_hash($_POST['password'], PASSWORD_DEFAULT)); $verification_code = bin2hex(random_bytes(16)); try { // تحقق من وجود البريد الإلكتروني $stmt = $conn->prepare("SELECT * FROM users WHERE email = ?"); $stmt->execute([$email]); if ($stmt->rowCount() > 0) { echo "<p>البريد الإلكتروني موجود بالفعل. يرجى استخدام بريد إلكتروني آخر.</p>"; } else { // إدخال بيانات المستخدم الجديدة $stmt = $conn->prepare("INSERT INTO users (username, email, password, verification_code, is_verified) VALUES (?, ?, ?, ?, 0)"); $stmt->execute([$username, $email, $password, $verification_code]); // إعدادات البريد الإلكتروني $to = $email; $subject = 'التحقق من عنوان البريد الإلكتروني'; $message = "يرجى النقر على الرابط التالي للتحقق من عنوان بريدك الإلكتروني: <a href='رابط صفحة التحقق?code=$verification_code'>التحقق من البريد الإلكتروني</a>"; $headers = "From:البريد الالكتروني خاصتي \r\n"; $headers .= "Reply-To:البريد الالكتروني خاصتي\r\n"; $headers .= "Content-type: text/html\r\n"; if (mail($to, $subject, $message, $headers)) { echo "<p>تم التسجيل بنجاح! تم إرسال بريد إلكتروني للتحقق إلى عنوان بريدك الإلكتروني.</p>"; } else { echo "<p>فشل في إرسال بريد التحقق.</p>"; } } } catch (PDOException $e) { echo "<p>حدث خطأ أثناء التسجيل: " . $e->getMessage() . "</p>"; } } ?> </body> </html>
    2 نقاط
  4. كيف اطلع ع مسوعة حسوب بخصوص هذا المجال (dictionaries) ؟ لم اجد التوبيب لذلك
    2 نقاط
  5. السلام عليكم بعد اكمال دورة تحليل البيانات والتعلم الالي وتنفيذ المشاريع ممكن الشخص يلاقي وظيفة مناسبة في تحليل البيانات عن بعد
    2 نقاط
  6. انا اعمل على مشروع بعنوان تطبيق لحجز صالات المناسبات باستخدام node js و mongoDB واريد تعلم هيكل mvc لانه يساعد على تنظيم المشروع وتطويره في المستقبل ، اريد شرح عن كيف ابدأ بتعلمه وكيف يمكن ان اقسم به ملفات مشروعي وتنظيمه ؟ اريد توضيح بالامتله وشكرا جزيلا
    1 نقطة
  7. السلام عليكم لماذا اثناء الضغط علي زر تعديل تظهر مشكلة تالية public function edit($id, Request $request) { $student = Student::findOrFail($id); return view('student.edit', ['student' => $student]); } public function update(Request $request, $id) { // Find the student by ID $student = Student::findOrFail($id); // Validate the input data $validatedData = $request->validate([ 'name_std' => 'required|string|max:255', 'num_std' => 'required|string|max:255', 'email_std' => 'required|email|max:255', 'date_student' => 'required|date', 'adress_std' => 'required|string|max:255', 'phone' => 'required|string|max:20', ]); // Update the student's details $student->name = $validatedData['name_std']; $student->registration_number = $validatedData['num_std']; $student->email = $validatedData['email_std']; $student->date_of_birth = $validatedData['date_student']; $student->address = $validatedData['adress_std']; $student->phone = $validatedData['phone']; $student->save(); // Return a success response return redirect()->route('student.index')->with('success', 'Student data updated successfully.'); } صفحة edit.blade.php <form action="{{ route('students.edit', $student->id) }}" class="form-inline" method="POST"> @csrf @method('patch') <div class="row"> <div class="col-md-4 mb-3"> <label for="name_std" class="form-label">اسم الطالب</label> <input type="text" class="form-control" id="name_std" name="name_std" placeholder=" اسم الطالب" style="width:80%;" value="{{ $student->name_std }}"> </div> <div class="col-md-4 mb-3"> <label for="num_std" class="form-label">رقم القيد</label> <input type="text" class="form-control" id="num_std" name="num_std" placeholder="رقم القيد" style="width:80%;" value="{{ $student->num_std }}"> </div> <div class="col-md-4 mb-3"> <label for="email_std" class="form-label">البريد الالكتروني</label> <input type="email" class="form-control" id="email_std" name="email_std" placeholder="البريد الالكتروني" style="width:80%;" value="{{ $student->email_std }}"> </div> <div class="col-md-4 mb-3"> <label for="date_student" class="form-label">تاريخ الميلاد</label> <input type="date" class="form-control" id="date_student" name="date_student" style="width:80%;" value="{{ $student->date_student }}"> </div> <div class="col-md-4 mb-3"> <label for="adress_std" class="form-label">العنوان</label> <input type="text" class="form-control" id="adress_std" name="adress_std" placeholder=" العنوان" style="width:80%;" value="{{ $student->adress_std }}"> </div> <div class="col-md-4 mb-3"> <label for="phone" class="form-label">رقم الهاتف</label> <input type="text" class="form-control" id="phone" name="phone" placeholder="رقم الهاتف" style="width:80%;" value="{{ $student->phone }}"> </div> </div> <button type="submit" class="btn btn-primary">تعديل</button> </form> <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\StudentController; use Illuminate\Routing\Route as RoutingRoute; Route::get('/student', [StudentController::class, 'index'])->name('/student'); Route::get('/student/create', [StudentController::class, 'create'])->name('/student/create'); Route::post('/student/create', [StudentController::class, 'store'])->name('/student/create'); Route::get('/students/{student}/edit', [StudentController::class, 'edit'])->name('students.edit'); Route::patch('/students/{student}/update', [StudentController::class, 'update'])->name('students.update');
    1 نقطة
  8. يظهر خطا بعد الضغط علي زر تعديل Undefined variable $PATCH /students/27/update HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate, br, zstd Accept-Language: ar,en-US;q=0.9,en;q=0.8 Cache-Control: max-age=0 Connection: keep-alive Content-Length: 170 Content-Type: application/x-www-form-urlencoded Cookie: XSRF-TOKEN=eyJpdiI6IjBWTkMyYlZTZUZ5cVpVT0tIaXl2bVE9PSIsInZhbHVlIjoiMGJQdEN4a3hFOVREUjlhWE1tVmV2cmRLbnBPdXU0WTVMazNmcWtmRTB1RW9GZHhYWkxkTzRzYmpXYS80THVXZU9ZOHFuWUZyWFpqMisrMmZ4T2gzZWs0SUtMeFRVYVBRb2svV2FnbUN6cmpOdVVHTGFrYUo0cFdtbHpLbU9zYTciLCJtYWMiOiJjMGQ3YzkwMzM5MjFkNGExOWNiYjJmZjRmZDFkNDkwOWEwYmFhOTdiY2U4YzljMDRmN2ExZDkxMDAwMDRlODFhIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6IlEwd0hhRkFGak9EenhicThQakpaUEE9PSIsInZhbHVlIjoiQllzVUZvN3BtdjlaQkQwM056aTliS2hlckYrZE5zM2tTQ2J6REp6SkszRmlNS0JmZDFGSjlUTVNrYy9PSitwMTNrS1k4V0FyZzhCMm80emxLVzZ0Ymdmd0xuMmJoN2pVTXNTYjNsR0s3UEZ3d2FYSU9XVjN4TEZLMEJLellpSE0iLCJtYWMiOiJmMzNjNDFhNjg1YTI2Y2MwOWI0ZmQ0ZDI2YWIyMDM2ZTU3MmEzM2JjZmRlOTMwMTVlYzFhZDI4MzFiYzQ0ZmZiIiwidGFnIjoiIn0%3D Host: 127.0.0.1:8000 Origin: http://127.0.0.1:8000 Referer: http://127.0.0.1:8000/students/27/edit Sec-Ch-Ua: "Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Cookie: XSRF-TOKEN=41DWMOmUJVMomEHkA3zhzHNboxEatwQDwpQ8RPE7; laravel_session=0J6yFcsnJ2rkS3PcNDmv0iP2my6vXmaHQ4DYhFlR _token=41DWMOmUJVMomEHkA3zhzHNboxEatwQDwpQ8RPE7&_method=patch&name_std=hmed&num_std=222222&email_std=ahmed%40gmail.com&date_student=2222-02-22&adress_std=libya&phone=3333
    1 نقطة
  9. لتفادي هذا الأمر يجب استخدام خادم بريد موثوق به بحيث يكون معدّا بشكل صحيح وأفضل الطرق من خلال إعداد سجلات SPF و DKIM و DMARC ففائدتها هي كالتالي: SPF: يساعد في التحقق من أن الخادم المُرسل مصرح له بإرسال البريد. DKIM: يضيف توقيعا رقميا للتحقق من صحة الرسائل. DMARC: يحدد كيفية التعامل مع الرسائل التي تفشل في اختبارات SPF أو DKIM. فتكوين سجلات DNS بشكل صحيح ضروري لمصادقة بريدك الإلكتروني يمكنك التسجيل في SPF (Sender Policy Framework) وDKIM (DomainKeys Identified Mail) وDMARC (Domain-based Message Authentication, Reporting, and Conformance) كي تساعد في تحسين مصداقية بريدك الإلكتروني. كما يجب أن تتجنب العناوين النصية العشوائية، وأن تقلل من الروابط. كما أنصح باختبار البريد الإلكتروني يمكنك استخدام أدوات مثل Mail Tester لتقييم رسائل البريد الإلكتروني الخاصة بك ومعرفة الأسباب التي قد تؤدي إلى تصنيفها كبريد غير مرغوب فيه.
    1 نقطة
  10. هذه ليست مشكلة متعلقة بالكود لتحسين إمكانية وصول رسائل البريد الإلكتروني إلى صندوق الوارد بدلاً من البريد غير المرغوب فيه (السبام)، يمكنك اتباع الخطوات التالية: تأكد من صحة إعدادات البريد الإلكتروني: استخدم عنوان بريد إلكتروني موثوق: استخدم عنوان بريد إلكتروني خاص بك يكون احترافيا ولا تقوم بإستخدام بريد جوجل بإسم مبهم أو يدل على حساب spam. تجنب إرسال رسائل البريد الإلكتروني بشكل كثير: لا ترسل رسائل كثيرة لنفس الحساب وذلك تجنب إرسال رسائل غير مرغوب فيها حيث يمكن أن يؤدي ذلك إلى وضع عنوان بريدك في قائمة البريد المزعج. استخدم خدمة إرسال بريد إلكتروني موثوقة: اختر موفر خدمة موثوق إذا كانت الإستضافة الخاصة بك توفر لك بريد إلكتروني فيفضل إستخادمها ويجب أن تكون إستضافة جيدة وأن يكون البريد الإلكتروني يحوي ال domain الخاص بك. ويمكنك قراءة الإجابة التالية فقد تساعدك في حل المشكلة لديك :
    1 نقطة
  11. السلام عليكم ممكن حل مشكلة لدي كود تالي لتعديل بيانات Route::get('/student', [StudentController::class, 'index'])->name('/student'); Route::get('/student/create', [StudentController::class, 'create'])->name('/student/create'); Route::post('/student/create', [StudentController::class, 'store'])->name('/student/create'); Route::get('/students/{student}/edit', [StudentController::class, 'edit'])->name('students.edit'); Route::patch('/students/{student}/update', [StudentController::class, 'update'])->name('students.update'); صفحة edit.blade.php @extends('layouts.master'); @section('title') ادخال بيانات @endsection @section('title_page1') الطلبة @endsection @section('title_page2') ادخال بيانات الطلبة @endsection @section('content') <style> label, button { margin-top: 1cm; } h5, button { margin-right: 1cm } label { text-align: right; display: inline-block; width: 140px; } </style> <form action="{{ route('/student/update', $student->id) }}" class="form-inline" method="POST"> @csrf @method('PUT') <div class="row"> <div class="col-sm-4 tight-gutter"> <label>اسم الطالب </label> <input type="text" class="form-control" name="name_std" style="width: 100%;" placeholder=" اسم الطالب" value="{{ $student->name_std }}" </div> <div class="col-sm-4 tight-gutter"> <label>رقم القيد</label> <input type="text" class="form-control" name="num_std" style="width: 100%;" placeholder="رقم القيد" value="{{ $student->num_std }}"> </div> <div class="col-sm-4 tight-gutter"> <label> البريد الالكتروني</label> <input type="email" class="form-control" name="email_std" style="width: 100%;" placeholder="البريد الالكتروني " value="{{ $student->email_std }}"> </div> <div class="col-sm-4 tight-gutter"> <label> تاريخ الميلاد</label> <input type="date" class="form-control" name="date_student" style="width: 100%;" value="{{ $student->date_student }}"> </div> <div class="col-sm-4 tight-gutter"> <label> العنوان</label> <input type="text" class="form-control" name="adress_std" style="width: 100%;" placeholder=" العنوان" value="{{ $student->adress_std }}"> </div> <div class="col-sm-4 tight-gutter"> <label>رقم الهاتف</label> <input type="text" class="form-control" name="phone" style="width: 100%;" placeholder="رقم الهاتف" value="{{ $student->phone }}"> </div> </div> <button type="submit" class="btn btn-primary">تعديل</button> </form> @endsection @section('scripts') <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"> </script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"> </script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"> </script> @endsection صفحة controller public function edit($id, student $student, Request $request) { return view('student.edit', ['student' => $student]); } public function update(Request $request, $id) { $student = Student::findOrFail($id); if ($request->isMethod('post') || $request->isMethod('put')) { $validatedData = $request->validate([ 'name_std' => 'required|string|max:255', 'num_std' => 'required|string|max:255', 'email_std' => 'required|email|max:255', 'date_student' => 'required|date', 'adress_std' => 'required|string|max:255', 'phone' => 'required|string|max:20', ]); $student->name = $validatedData['name_std']; $student->registration_number = $validatedData['num_std']; $student->email = $validatedData['email_std']; $student->date_of_birth = $validatedData['date_student']; $student->address = $validatedData['adress_std']; $student->phone = $validatedData['phone']; $student->save(); return redirect()->route('student.index')->with('success', 'Student data updated successfully.'); } }
    1 نقطة
  12. للبحث في موسوعة حسوب يمكنك الذهاب للصفحة الرئيسية ومن ثم كتابة ما تردي البحث عنه في حقل البحث وسيظهر لك وهذا هو رابط الصفحة الرئيسية : https://wiki.hsoub.com/الصفحة_الرئيسية أو يمكنك من خلال الصفحة الرئيسية إختيار اللغة التي تريد قراءة الدروس لها وفي حالتك تريد لغة بايثون وستجد في أعلى الصفحة فهرس لجميع الدروس يمكنك البحث عن الذى تريده من خلاله . أما بالنسبة للرابط الخاص بدرس dictionaries فتفضل هذا هو : https://wiki.hsoub.com/Python/dict
    1 نقطة
  13. بنسبة كبيرة نعم فأنت تقوم بالأتي:- 1- تقسيم الكود الخاص بك إلى دوال صغيرة ليسهل التعامل معها. 2- التعامل مع الأخطاء وإرسال رسالة بالخطأ في كل جزء يسهل العملية أيضا. 3 -إرسال كود حالة مثل (200 ، 500، 201) جيدا أيضا. 4-طريقة التسمية وكل شئ يقوم بما تم تسميته به جيد. 5- كتباتك لتوثيق الدالة مثل هذا جيد ضعه لكل الدوال أيضا. /** * Method: POST * route : /api/auth/login * */ استمر على هذا النهج ومع الوقت ستتطور أكثر وأكثر. بالتوفيق..
    1 نقطة
  14. مارأيك بطريقة كتابة الكود. هل تخضع لbest practice
    1 نقطة
  15. بناء على الشيفرة خاصتك، ففي ملف generateToken.js، تقوم بتعيين اسم الـ cookie كـ 'token' هنا: response.cookies.set('token', token, { }); لكن في ملف protect.js، تحاول الحصول على الـ cookie باسم 'jwt': const token = cookieStore.get('jwt')?.value; لذا يجب أن يكون اسم الـ cookie متطابقاً في كلا الموضعين. كما أني لا أرى أنك قمت باستيراد مكتبة jsonwebtoken في ملف protect.js لذا يجب إضافة هذا الاستيراد: import jwt from 'jsonwebtoken'; أما فيما يخص كيفية التعامل مع الـ response في ملف generateToken.js ففي الدالة setTokenCookie، تستخدم response.cookies.set، لكن في Next.js 14، يجب استخدام cookies() من next/headers كالتالي: import { cookies } from 'next/headers'; const setTokenCookie = (token) => { cookies().set('token', token, { httpOnly: true, secure: process.env.NODE_ENV !== 'development', sameSite: 'strict', maxAge: 60*60*24 }); } أما في ملف login/route.js، يجب تعديل كيفية استخدام setTokenCookie إلى: if (user) { const token = generateToken(user._id); setTokenCookie(token); return NextResponse.json({ user: user.email }, { status: 200 }); } else { return new NextResponse("Failed to create user", { status: 500 }); } واحرص على أن تكون قمت بتعريف ال JWT_SECRET في ملف .env، أرجو تصحيح الأخطاء التالية مع إرفاق صورة للخطأ الذي تواجهه في حالة استمرار المشكلة.
    1 نقطة
  16. المشكلة في middlewares/protect.js في هذا السطر const token = cookieStore.get('jwt')?.value; حيث تريد الوصول للكوكيز باسم jwt وهي غير موجودة لأنك في utils/generateToken عند وضع الكوكيز كانت باسم token وليس jwt response.cookies.set('token', token, { ^^^^^ httpOnly: true, secure: process.env.NODE_ENV !== 'development', sameSite: 'strict', maxAge: 60*60*24 }); لذا نقوم بتعديل هذا السطر في middlewares/protect.js ليصبح ليتم الوصول للكوكيز بشكل صحيح const token = cookieStore.get('token')?.value; وأيضا قم باستيراد الحزمة jwt أعلى ملف middlewares/protect.js ليتم الوصول منها للدالة ()verify حيث أننا ننريدها ليتم فك تشفير token بعد ذلك. import jwt from 'jsonwebtoken' بالتوفيق...
    1 نقطة
  17. أي درس ؟ أنا أتابع كورس من اليوتيوب فقط ليس هنا.
    1 نقطة
  18. from fastapi import FastAPI import uvicorn import os from DeepImageSearch import Load_Data, Search_Setup import shutil os.environ['KMP_DUPLICATE_LIB_OK']='True' app = FastAPI() @app.post("/api/request-similar-images") async def get_user_image(user_image: dict): # Access the data sent by the user try : img = user_image.get("image") # image_list = Load_Data().from_folder(['\image_search\Demo_Data']) # go back one directory path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..')) # go to \storage\app\public\image-search image_list = os.path.abspath(os.path.join(path, 'storage/app/public/image-search')) # Set up the search engine, You can load 'vit_base_patch16_224_in21k', 'resnet50' etc more then 500+ models st = Search_Setup(image_list=image_list, model_name='vgg19', pretrained=True, image_count=len(image_list)) # Get metadata metadata = st.get_image_metadata_file() st.add_images_to_index([img]) img_dict , images_and_scores = st.get_similar_images(image_path=img, number_of_images=100) paths_list = [] for index , path in img_dict.items(): paths_list.append(path) scores_list = [] for index , path in images_and_scores.items(): scores_list.append(path) similarty_list = dict(zip(paths_list, scores_list)) similarty_list = [{key: value} for key, value in similarty_list.items()] for i, d in enumerate(similarty_list): mydict = similarty_list[i] for key, value in mydict.copy().items(): if value == 0.0 : del mydict[key] while {} in similarty_list: similarty_list.remove({}) transformed_list = [ {"path": list(item.keys())[0], "score": list(item.values())[0]} for item in similarty_list] return transformed_list except Exception as e: print (e) return "No image found." if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=5000) عندما ارسال اكثر من request من خلال Postman او استخدام ال endpoint في اي مكان اخر. المشكله انه يجب الانتظار على كل request حتى الانتهاء ليبدا ال request الذي بعدة كيف يمكننى حل هذه المشكلة
    1 نقطة
  19. وعليكم السلام ورحمة الله وبركاته. يوجد لديك خطأين في ملف edit.blade.php : الخطأ هنا يجب توفير إسم ال route وليس المسار والحل هو التالي : action="{{ route('students.update', $student->id) }}" الخطأ الثاني سيظهر لك عند إرسال ال form حيث أنك حددت نوع المسار patch ولكنك ترسل put لذلك الحل هو إستبدال السطر السابق ب patch أو تغير نوع الطلب في web.php إلى put و يمكنك إستبدال السطر السابق بالكود التالي : @method('PATCH')
    1 نقطة
  20. وعليكم السلام ورحمة الله وبركاته . return و print() هما عمليتان تستخدمان في البرمجة ولكن لكل منهما دور مختلف . return: يُستخدم في الدوال (functions) لإرجاع قيمة من الدالة إلى المكان الذي تم استدعاؤها منه. عندما يتم تنفيذ return يتم إنهاء تنفيذ الدالة على الفور ويتم إرسال القيمة المحددة إلى الجهة التي استدعت الدالة ويتم تجاهل أي أكواد داخل الدالة بعد سطر return. يمكن استخدام القيمة التي يتم إرجاعها في حسابات أخرى أو تخزينها في متغيرات. مثال: def add(a, b): return a + b result = add(5, 3) # result سيكون 8 print(): تستخدم لعرض البيانات أو الرسائل على شاشة المستخدم. لا يؤثر print() على قيمة الدالة أو عملية التنفيذ. إنه مجرد وسيلة لعرض المعلومات وطباعتها للمستخدم. يمكن استخدام print() لإكتشاف الأخطاء و لعرض النتائج، أو لطباعة المعلومات للمستخدم. مثال: def add(a, b): result = a + b print("The result is:", result) add(5, 3) # سيظهر "The result is: 8" على الشاشة تلخيصا return يتم استخدامه لإرجاع القيم من الدوال لاستخدامها لاحقًا، بينما print() يُستخدم لعرض المعلومات على الشاشة دون التأثير على القيم التي يتم إرجاعها من الدوال.
    1 نقطة
  21. لكل منهما وظيفة مختلفة ف return تستخدم لإرجاع قيمة من دالة إلى المكان الذي تم استدعاء الدالة منه، كما أنه بعد تنفيذ جملة return يتم إنهاء تنفيذ الدالة ويُعاد القيمة المحددة، و يمكن استخدام القيمة المرجعة في العمليات اللاحقة، مثل تخزينها في متغير أو استخدامها في حسابات. بينما print تستخدم لطباعة المعلومات إلى الشاشة أو إلى مكان الإخراج المخصص، مثل وحدة التحكم أو سطر الأوامر، و لا تعيد أي قيمة من الدالة، بل تقوم فقط بعرض المعلومات للمستخدم، كما أنها لا تؤثر على القيم التي قد تحتاجها العمليات البرمجية الأخرى. و يمكنك أن تطلع أكثر على الفرق بينهما من خلال هذا السؤال:
    1 نقطة
  22. return و print() هما كلمتان مفتاحيتان في العديد من لغات البرمجة، وprint() باختصار نستخدمها لعرض قيمة معينة على الشاشة تقوم بطبع القيمة المحددة ثم تستمر في تنفيذ الكود التالي، كما أنها لا تعيد أيّ قيمة أي لا يمكن تخزين النتيجة التي تم طباعتها في متغير لاستخدامها لاحقا. بينما return فتستخدم لإرجاع قيمة من دالة إلى المكان الذي تم استدعاء الدالة منه عندما يصل التنفيذ إلى عبارة return، تتوقف الدالة عن العمل وتعيد القيمة المحددة أي أنه يمكن تخزين القيمة المرجعة في متغير لاستخدامها لاحقا في عمليات حسابية أو في دالة أخرى. يمكنك الاطلاع أكثر من هنا:
    1 نقطة
  23. وعليكم السلام ورحمة الله وبركاته إذا اطلعنا على معرض الأعمال من الخارج نجد أن موقع مستقل يأخذ الصورة بشكل متوسط مهما كانت كبيرة , فلا بأس من استخدام صور أكبر من المقاس العادي . الآن .... إذا نظرنا لمقاس الصورة الخارجية ((الغلاف)) نجد أن مقاساتها كالتالي : في الكمبيوتر : 346px * 200px في الجوال : 246px * 200px فأفضل خيار يمكنك اختياره هو مقاس الكمبيوتر لهذه الصورة أو مضاعفته ليبدو بدقة أعلى : 692px * 400px . بالنسبة للصور الداخلية , فالمقاسات كالتالي : في الكمبيوتر : 718px * طول غير محدد في الجوال : 332px * طول غير محدد فأفضل خيار أيضاً يمكنك اختياره هو مقاس الكمبيوتر لهذه الصورة أو مضاعفته ليبدو بدقة أعلى : 1436px * طول غير محدد. ملاحظة مهمة : لا ينصح باستخدام صور طويلة ضمن العمل , لأنها ستبدو كبيرة جداً ويضطر المستخدم للنزول لرؤية كافة الصورة .
    1 نقطة
  24. مقدمة إن التعوّد على سطر الأوامر هي الخطوة الأولى نحو الاستفادة من قوة منصة خادوم لينكس، وهو شرط أساسي لجميع نشاطات المرتبطة بالخواديم والتي قد تتمنى القيام بها في هذه البيئة. على الرغم من وجود بدائل رسومية للعديد من الأدوات إلا أن تعلم سطر الأوامر مهارة ستسمح لك بالعمل بكفاءة وسرعة ومرونة بطريقة لا يمكنك فعلها مع أغلب الواجهات الرسومية (GUI). يجب علينا أن نبدء من مكان ما، لذلك في هذا المقال سوف نغطي الأساسيات: كيف تتنقل في النظام واكتشاف ما حولنا. متطلبات أساسية هذا المقال بسيط وأساسي، لذلك فهو لا يتطلب الكثير من المعرفة المسبقة، ومع ذلك، ستحتاج إلى تسجيل الدخول إلى خادومك الخاص لتبدأ الاستكشاف. الخيارات التي لديك للقيام بهذا تعتمد على نظام التشغيل الذي تستخدمه في المنزل. عندما تنشئ DigitalOcean droplet جديد، سوف يرسلون رسالة عبر البريد الإلكتروني تحتوي على كلمة السر و عنوان IP خاص للوصول إلى خادومك الجديد، استخدم هذا الرابط لمعرفة كيفية الاتصال بخادوم VPS الخاص بك. ssh root@your_IP وثمة خيار آخر عن طريق استخدام زر “Console Access” في الزاوية العلوية على اليمين من لوحة تحكم DigitalOcean، هذا الأمر سينشئ لك طرفية افتراضية مباشرة في نافذة متصفحك. معرفة موقعك عن طريق pwd في هذه المرحلة، يجب أن تكون قد سجلت دخولك إلى خادوم لينكس الخاص بك، وسوف ترى في الغالب شيئا مشابهًا لهذا: root@your_hostname:~# هذا هو الموجه (prompt) حيث نكتب الأوامر، وليس هذا فقط، بل أنت حاليا في مكان محدد في نظام ملفات الخادوم حيث ستكون دائما في مكان معين في التسلسل الهرمي للملفات وهذا الأمر يؤثر على كيفية عمل الأوامر التي تكتبها. هذا الأمر يشبه قيامك بفتح متصفح الملفات في حاسوبك المحلي، يمكنك الضغط على مختلف المجلدات للانتقال إلى مناطق مختلفة من نظام الملفات، وإذا ذهبت إلى قائمة التعديل (edit menu) في متصفح الملفات، سوف تجد بعض الخيارات التي ستُطبق على العناصر الموجودة في المجلد التي أنت فيه، وسطر الأوامر هو تمثيل نصي لنفس الفكرة. فأين نحن الآن بالضبط في نظام ملفاتنا؟ هنالك دليل واحد موجود في الموجه نفسه، فقبل رمز # أو $ في نهاية الموجه (هذا سيعتمد على المستخدم الذي سجّل دخوله)، سوف ترى رمزًا خاصًا ~ وهذا يعني أنك موجود في مجلد المنزل (home). مجلد المنزل هو المكان الذي يتم تخزين ملفات المستخدم، فالرمز ~ هو اختصار لهذا المجلد. هنالك طريقة أخرى لمعرفة موقعنا في نظام الملفات وهي عن طريق استخدام الأمر pwd وهذا الأمر سيكون أول أمر سنتعلمه. اكتب هذه الحروف على الطرفية واضغط على زر الإدخال (Enter): pwd /root إن /root هو مجلد المنزل للمستخدم للمستخدم الجذر (المدير)، إذا كنت قد سجّلت دخولك باستخدام مستخدم آخر، فسوف ترى شيئًا مشابهًا لهذا: pwd /home/your_username في هذا الدرس، لا يهم المستخدم الذي سجّلت دخولك به، فأي من النتيجتين ظهرت لك فهي مناسبة. النظر حولك باستخدام ls الآن أنت تعرف مكانك وفي أي مجلد أنت، لكن لازلت تجهل ما هي المحتويات الأخرى الموجودة في ذلك المجلد، فكيف تستطيع معرفة ذلك؟ ببساطة يمكننا سؤال الخادوم عن الملفات والمجلدات الموجودة في المجلد الحالي عن طريق استخدام الأمر ls، أكتبه الآن على الموجه: ls بعد كتابة هذا الأمر ستعود (في الغالب) إلى موجه الأوامر ولن تحصل على أية معلومات، فهل فشلت عملية تنفيذ هذا الأمر؟ لا، على العكس فقد نجحت لكنه ببساطة ليس هنالك أية ملفات أو مجلدات في مجلدك الحالي. دعونا ننشئ بعض ملفات التجريبية لنرى كيف يعمل الأمر ls عند وجود ملفات في المجلد، أكتب هذا الأمر لإنشاء بضعة ملفات: touch file{1..5} السطر السابق سينشئ لنا 5 ملفات بأسماء file1 و file2… في مجلدك الحالي. لنُجرب الأمر ls لنرى كيف سيتصرف الآن: ls file1 file2 file3 file4 file5 رائع، تعرّف الآن أمر ls على الملفات الموجودة في مجلد المنزل. أغلب الأوامر لديها سلوكيات افتراضية يتم تنفيذها عند استدعائها كما فعلنا في الأعلى، ومع ذلك، فإن أغلب سلوكيات الأمر يمكن التحكم بها عن طريق تمرير المعاملات الاختيارية إليها، وهذه الأخيرة يشار إليها بأسماء عديدة مثل الخيارات “options” والمعاملات “arguments/parameters” والأعلام “flags”… في بعض الأحيان، هذه المعاملات تُفعّل الوظائف الاختيارية المتاحة من خلال الأمر وفي أحيان آخرى تحدد الكائن الذي يجب على الأمر أن يتجنبه. لنبدأ مع الحالة الأولى. استكشاف خيارات ls تقريبا جميع الأوامر تملك خيار المساعدة، وفي أغلب الأوقات يمكنك الوصول إليه عن طريق إضافة --help أو -h إلى نهاية الأمر، يمكنك الآن تجربة هذا مع أمر ls: ls --help Usage: ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. Mandatory arguments to long options are mandatory for short options too. -a, --all do not ignore entries starting with . -A, --almost-all do not list implied . and .. --author with -l, print the author of each file -b, --escape print C-style escapes for nongraphic characters --block-size=SIZE scale sizes by SIZE before printing them. E.g., . . . سيعطيك هذا بعض الإرشادات حول الاستخدام الصحيح للأمر بالإضافة إلى لمحة حول الخيارات المتاحة لتغيير السلوك الإفتراضي للأوامر. العمود الأيسر يعطيك الحروف التي يجب كتابتها وتمريرها إلى الأمر لتنفيذ ما يوجد في وصف العمود الأيمن. إن --help التي قمنا بإضافتها هي مثال لخيار يمكننا تمريره. ومن الطرق الأخرى لمعرفة الخيارات المتاحة لأمر معين هي عن طريق التحقق من الدليل “manual”، ويمكنك فعل ذلك عن طريق كتابة man متبوعا بالأمر الذي تريد معرفة خياراته. قم بتجربة هذا الآن: man ls يمكنك التنقل في الصفحة كما تشاء عن طريق مفاتيح الأسهم والخروج عن طريق كتابة q. كما ترى، يمتلك ls بضعة خيارات يمكنك تمريرها إلى الأمر لتغيير سلوكه، دعونا نجرب بعضها. ls -l -rw-r--r-- 1 root root 0 Feb 28 19:45 file1 -rw-r--r-- 1 root root 0 Feb 28 19:45 file2 -rw-r--r-- 1 root root 0 Feb 28 19:45 file3 -rw-r--r-- 1 root root 0 Feb 28 19:45 file4 -rw-r--r-- 1 root root 0 Feb 28 19:45 file5 السطر السابق يعرض لنا نفس الملفات الخمسة السابقة لكنه يعرضها بشكل أطول، وهذا الأمر يعطينا المزيد من المعلومات حول الملفات مثل المالك (“root” الأولى)، والمجموعة المالكة (“root” الثانية)، وحجم الملف (0) بالإضافة إلى تاريخ آخر تعديل وبعض المعلومات الأخرى. لنجرب خيارًا آخر: ls -a . .aptitude .bashrc file2 file4 .profile .ssh .. .bash_history file1 file3 file5 .rnd .viminfo عرض لنا هذا الخيار ملفات لم نرها من قبل، إن المعامل -a مرادف للمعامل –all والذي يعرض لنا جميع الملفات الموجودة في المجلد الحالي بما في ذلك الملفات المخفية. في أنظمة لينكس، جميع الملفات التي يبدأ اسمها بنقطة سيتم إخفائها بشكل افتراضي، وهذه الملفات ليست سرية ويمكن لأي شخص إيجادها وتم الحفاظ عليها بهذه الطريقة لتسهيل عملية إدارة الملفات، وعند تمرير -a فسنأمر ls بعرض هذه الملفات المخفية أيضا. يمكننا تمرير عدة معاملات كذلك، وذلك عن طريق وضعهم معا كالتالي: ls -l -a drwx------ 4 root root 4096 Feb 28 19:45 . drwxr-xr-x 23 root root 4096 May 3 2013 .. drwx------ 2 root root 4096 Feb 28 17:19 .aptitude -rw------- 1 root root 2036 Feb 28 18:20 .bash_history -rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc -rw-r--r-- 1 root root 0 Feb 28 19:45 file1 . . . الأمر السابق سيعمل بدون مشاكل، لكن يمكننا أيضا دمج المعاملات كالتالي: ls -la هذه الطريقة ستعمل بالضبط كالطريقة الأولى وتتطلّب وقت أقل للكتابة. ومن الخيارات الأخرى المفيدة خيار -R والذي سيعرض جميع الملفات والمجلدات (ومحتوياتها)، وبما أن المجلدات الموجودة في مجلد المنزل الخاص بنا مخفية، فسنمرر خيار -a أيضا: ls -Ra .: . .aptitude .bashrc file2 file4 .profile .ssh .. .bash_history file1 file3 file5 .rnd .viminfo ./.aptitude: . .. cache config ./.ssh: . .. authorized_keys الآن عرفنا كيف نغير سلوكيات ls، لنغير الآن “الكائن” الذي يعمل عليه ls. استخدام ls في مجلدات أخرى افتراضيا، سيعرض ls محتويات المجلد الحالي، ومع ذلك يمكنك تمرير اسم أي مجلد تريد أن ترى محتوياته في نهاية الأمر. على سبيل المثال، يمكننا رؤية محتويات مجلد /etc الموجود في جميع أنظمة لينكس بكتابة السطر التالي: ls /etc acpi fstab magic rc.local adduser.conf fstab.d magic.mime rc.local.orig aliases fuse.conf mailcap rcS.d aliases.db gai.conf mailcap.order reportbug.conf alternatives groff mailname resolvconf anacrontab group mail.rc resolv.conf apm group- manpath.config rmt . . . كما ترى فإن هنالك الكثير من الملفات في هذا المجلد. أي مسار لمجلد يبدأ بخط مائل (/) يُعرف على أنه مسار “مطلق” وسبب ذلك أنه يشير إلى أعلى مسار المجلد والذي هو مجلد الجذر. ومن الطرق الأخرى للإشارة إلى مجلد هي عن طريق استخدام المسار “النسبي”، وهذا سوف يبحث عن مجلد نسبي مرتبط بالمجلد الذي تتواجد به أنت الآن، وهذه المجلدات لا تبدأ بخط مائل. لا نملك أية مجلدات غير مخفية في مجلدنا الحالي لذلك سننشئ بعضها بسرعة وسنضيف بعض الملفات داخلها، لا تقلق حول عدم فهمك لهذه الأوامر في الوقت الحالي، فهذه الأوامر لإنشاء ملفات فقط لاستعمالها في الاستكشاف، لذلك أُكتبها كما هي: mkdir dir{1..3} touch dir{1..3}/test{A,B,C} سينشئ لنا هذا بعض المجلدات بداخلها ملفات، يمكننا رؤية هذه المجلدات باستخدام أمر ls عادي: ls dir1 dir2 dir3 file1 file2 file3 file4 file5 حتى نتمكن من رؤية ما بداخل مجلد dir1، يمكننا أن نعطي مسارًا مُطلقًا كما في المثال السابق، بإضافة المجلد الذي نريد رؤيته إلى نهاية قيمة مجلدنا الحالي، وسنتمكن من معرفة مجلدنا الحالي عن طريق الأمر التالي: pwd /root وبعد ذلك أضف المجلد الذي نهتم به إلى النهاية: ls /root/dir1 testA testB testC لم نكن مُجبرين على القيام بذلك، يمكننا ببساطة الإشارة إلى المجلدات الموجودة داخل مجلدنا الحالي بأسمائها فقط، كالتالي: ls dir1 testA testB testC إذا لم نبدأ المسار بخط مائل، فسيبحث نظام التشغيل على المسار المجلد الذي يبدأ بمجلدنا الحالي. التجوال في المكان حتى الآن، تعلمنا كيف نجد موقعنا في نظام الملفات كما أننا تعلمنا كيف نستخدم الأمر ls لمعرفة بعض المعلومات حول الملفات الموجودة في مجلدات معينة. لكن كيف نغيّر مجلد عملنا؟ تغيير مجلد عملنا سيسمح لنا باستخدام مسارات مترابطة من أماكن مختلفة ﻷنه في العادة، سيكون من السهل إدارة الملفات في المجلد الذي يحتويها. يمكننا التنقل حول التسلسل الهرمي للملفات باستخدام الأمر cd، هذا الأمر يغيّر المجلد الحالي إلى أي مجلد آخر. هذا أبسط استخدام لهذا الأمر: cd لا يبدو أن هنالك أية نتيجة، في الحقيقة، لم يحدث أي شيء، فعند تنفيذ الأمر cd بدون معلومات إضافية فسيغير موقعك الحالي إلى مجلد المنزل، وبما أننا في مجلد المنزل فلن يقوم الأمر بأي شيء. الطريقة الأساسية لاستخدام هذا الأمر هي كالتالي: cd /path/to/directory في هذا المثال، يمكنك استبدال /path/to/directory بمسار المجلد الذي تريد الانتقال إليه، فعلى سبيل المثال، إذا أردت الانتقال إلى مجلد الجذر، والذي سيكون مساره مجرد خط مائل / لأنه في أعلى شجرة الملفات، يمكننا كتابة التالي: cd / ملاحظة: المجلد الجذر (الذي أشرنا إليه بخط مائل /) يختلف عن مجلد المنزل للمستخدم الجذر (الموجود في /root)، وهذا الأمر سيربكك في البداية، لكن تذكر فقط أن المجلد الأعلى في شجرة نظام الملفات يدعى بالجذر. ستلاحظ أن موجه الأوامر قد تغير، بالضبط قبل رموز # أو $، فالمجلد قد تغير من ~ (تذكر أن رمز ~ يشير إلى مجلد المنزل للمستخدم) إلى مجلد الجذر لنظام الملفات. يمكننا التأكد من موقعنا عن طريق استخدام الأمر pwd مرة أخرى: pwd / كما يمكننا التحقق من الملفات الموجودة في مجلدنا الجديد: ls bin etc lib media proc sbin sys var boot home lib64 mnt root selinux tmp vmlinuz dev initrd.img lost+found opt run srv usr نجحنا بالتحرك نحو مكان جديد، لنحاول الآن الانتقال إلى مجلد جديد باستخدام المسار النسبي (relative path)، هنالك مجلد يدعى usr داخل مجلدنا الحالي، لننتقل إليه عن طريق كتابة: cd usr كما ترون، يمكننا استخدام المسار النسبي مع cd أيضا، والآن كيف نستطيع العودة إلى مجلد الجذر مرة أخرى؟ يمكننا كتابة نفس الأمر الذي استخدمناه سابقا cd /، لكننا سنجرب شيئًا مُختلفًا. لنجرب الانتقال إلى أعلى الشجرة باستخدام المسارات النسبيّة، فكيف نشير إلى المجلد الذي يحتوي مجلدنا الحالي باستخدام المسارات النسبيّة؟ ببساطة يمكننا الإشارة إلى المجلد الذي يحتوي على مجلدنا الحالي والذي يدعى بمجلد الأب باستخدام نقطتين (..). لنعد بمقدار مستوى واحد إلى الأعلى: cd .. pwd / كما ترى عدنا إلى مجلد الجذر. يمكننا أيضا الإشارة إلى مجلدنا الحالي باستخدام نقطة واحدة: ls . bin etc lib media proc sbin sys var boot home lib64 mnt root selinux tmp vmlinuz dev initrd.img lost+found opt run srv usr ستكون هذه مفيدة جدا في العديد من الحالات والتي لن نتعلمها في هذه المرحلة لكنك ستتمكن من الإشارة إلى مجلدك الحالي بسهولة في مراحل لاحقة. كما قلنا سابقا، إن رمز “~” يشير إلى مجلد المنزل، لنستخدم ذلك كبداية لمسار مجلد “dir1” الموجود داخل مجلد المنزل: cd ~/dir1 pwd /root/dir1 انتقلنا الآن إلى مجلد داخل مجلد المنزل بطريقة سهلة باستخدام رمز “~” التي وضعناها في الجزء الأول من المسار. لكن ماذا لو نسيت القيام بشيء في المجلد السابق وتريد العودة إليه؟ يمككنا العودة إلى مجلدنا السابق بكتابة التالي: cd - pwd / عدنا إلى مجلدنا السابق. لنختم الدرس بالعودة إلى مجلد المنزل، يمكننا فعل ذلك باستخدام ~ كمسار للتبديل أو يمكنك أيضا استخدام الوضع الافتراضي لـ cd للعودة إلى مجلد المنزل إذا لم نضف أي مسار إلى الأمر، لنجرب ذلك: cd pwd /root كما ترى، نجحنا في العودة إلى مجلد المنزل. الخاتمة ستمتلك الآن الأدوات التي تحتاجها لاستكشاف نظام الملفات، فعلى الرغم من أنك لم تكتشف كيف تقرأ الملفات إلا أنك أصبحت قادرا على التجوال وتصفح النظام بسهولة بالإضافة إلى قدرتك على معرفة مكانك والملفات حولك. ترجمة -وبتصرف- للمقال: How To Use cd, pwd, and ls to Explore the File System on a Linux Server لصاحبه Justin Ellingwood
    1 نقطة
×
×
  • أضف...