سرور مجازی

  • ۰
  • ۰

نحوه راه اندازی WireGuard در Rocky Linux 8

ورود به سایت

 

معرفی

WireGuard یک شبکه خصوصی مجازی سبک (VPN) است که از اتصالات IPv4 و IPv6 پشتیبانی می کند. VPN به شما امکان می دهد شبکه های غیرقابل اعتماد را مانند یک شبکه خصوصی پشت سر بگذارید. این به شما این آزادی را می دهد که از طریق تلفن هوشمند یا لپ تاپ خود با خیال راحت و ایمن به اینترنت متصل شوید ، وقتی به یک شبکه غیرقابل اعتماد متصل هستید ، مانند WiFi در هتل یا کافی شاپ.

رمزگذاری WireGuard برای ایجاد یک تونل رمزگذاری شده بین خود به کلیدهای عمومی و خصوصی برای همکاران متکی است. هر نسخه از WireGuard از مجموعه رمزنگاری خاصی برای اطمینان از سادگی ، امنیت و سازگاری با همسالان استفاده می کند.

در مقایسه ، سایر نرم افزارهای VPN مانند OpenVPN و IPSec از امنیت لایه انتقال (TLS) و گواهینامه ها برای احراز هویت و ایجاد تونل های رمزگذاری شده بین سیستم ها استفاده می کنند. نسخه های مختلف TLS شامل پشتیبانی از صدها مجموعه و الگوریتم رمزنگاری مختلف است ، و در حالی که این امر انعطاف پذیری بالایی را برای پشتیبانی از مشتریان مختلف امکان پذیر می کند ، همچنین پیکربندی VPN ای را که از TLS وقت گیرتر ، پیچیده تر و مستعد خطا است ، ایجاد می کند.

در این آموزش ، شما WireGuard را روی سرور Rocky Linux 8 راه اندازی می کنید و سپس دستگاه دیگری را پیکربندی می کنید تا با استفاده از هر دو اتصال IPv4 و IPv6 (که معمولاً به عنوان اتصال دو پشته نامیده می شود) به آن به صورت همتا متصل شود. همچنین می توانید نحوه هدایت ترافیک اینترنتی همتا را از طریق سرور WireGuard در پیکربندی دروازه ، علاوه بر استفاده از VPN برای یک تونل peer-to-peer رمزگذاری شده ، یاد بگیرید.

برای اهداف این آموزش ، ما سیستم Rocky Linux 8 دیگری را به عنوان همکار (که به آن مشتری نیز گفته می شود) در سرور WireGuard پیکربندی می کنیم. آموزش های بعدی این مجموعه نحوه نصب و اجرای WireGuard را در سیستم ها و دستگاه های Windows ، macOS ، Android و iOS توضیح می دهد.

پیش نیازها

برای پیگیری این آموزش ، شما نیاز دارید:

  • یک سرور Rocky Linux 8 با یک کاربر sudo غیر روت و فایروال فعال است. برای تنظیم این ، می توانید راه اندازی سرور اولیه ما را با آموزش Rocky Linux 8 دنبال کنید. ما در این راهنما از این به عنوان سرور WireGuard یاد می کنیم.
  • شما به یک ماشین مشتری نیاز دارید که از آن برای اتصال به سرور WireGuard خود استفاده کنید. در این آموزش ما به این دستگاه به عنوان WireGuard Peer اشاره می کنیم. برای اهداف این آموزش ، توصیه می شود از دستگاه محلی خود به عنوان WireGuard Peer استفاده کنید ، اما در صورت تمایل می توانید از سرورهای راه دور یا تلفن های همراه به عنوان مشتری استفاده کنید. اگر از سیستم از راه دور استفاده می کنید ، حتماً در قسمت های بعدی این آموزش ، تمام قسمت های اختیاری را دنبال کنید ، در غیر این صورت ممکن است خود را از سیستم خارج کنید.
  • برای استفاده از WireGuard با IPv6 ، همچنین باید اطمینان حاصل کنید که سرور شما پیکربندی شده است تا از این نوع ترافیک پشتیبانی کند. اگر می خواهید پشتیبانی IPv6 را با WireGuard فعال کنید و از قطره vpsgol استفاده می کنید ، لطفاً به این صفحه مستندات نحوه فعال کردن IPv6 در Droplets مراجعه کنید. هنگام ایجاد Droplet یا پس از آن با استفاده از دستورالعمل های آن صفحه ، می توانید پشتیبانی IPv6 را اضافه کنید.

مرحله 1 – نصب WireGuard و ایجاد یک جفت کلید

اولین قدم در این آموزش نصب WireGuard روی سرور شماست. برای شروع ، باید دو مخزن نرم افزار اضافی به فهرست بسته سرور خود ، epel و elrepo اضافه کنید. برای نصب آنها دستور زیر را اجرا کنید. توجه داشته باشید اگر در این جلسه برای اولین بار است که از sudo استفاده می کنید ، از شما خواسته می شود که رمز عبور کاربر sudo خود را ارائه دهید:

sudo dnf install elrepo-release epel-release

اکنون که سرور شما می تواند به مخازن موجود در بسته های WireGuard دسترسی پیدا کند ، WireGuard را با استفاده از دستورات زیر نصب کنید:

sudo dnf install kmod-wireguard wireguard-tools

اکنون که WireGuard را نصب کرده اید ، گام بعدی ایجاد تعمیر کلید خصوصی و عمومی برای سرور است. برای ایجاد کلیدها از دستورات wg genkey و wg pubkey استفاده می کنید و سپس کلید خصوصی را به فایل پیکربندی WireGuard اضافه می کنید.

از آنجا که شما در حال ایجاد یک کلید خصوصی هستید که برای رمزگذاری ترافیک در سرور WireGuard شما استفاده می شود ، مجوزهای پیش فرض اعمال شده بر روی پرونده های جدید باید قبل از ایجاد این فایل به طور موقت به یک مقدار محدود کننده تغییر کند. باید با استفاده از دستور umask مجوزهای پیش فرض را برای فایل های تازه ایجاد شده تنظیم کنید.

از دستور umask زیر برای اطمینان از ایجاد دایرکتوری ها و فایل های جدید  با مجوزهای محدود خواندن و نوشتن استفاده کنید:

umask 077

umask 077 اطمینان می دهد که فقط صاحب یک دایرکتوری می تواند در آن وارد شود و فقط صاحب یک فایل می تواند آن را بخواند یا بنویسد. مجدداً توجه داشته باشید که وقتی از پوسته خود خارج می شوید و دوباره وارد سیستم می شوید ، umask شما به مقدار پیش فرض 022 بازنشانی می شود ، که به شما اجازه می دهد فایل های جدیدی را که در سیستم ایجاد شده است بخوانید.

حالا می توانید با استفاده از دستور زیر کلید خصوصی را برای WireGuard ایجاد کنید:

wg genkey | sudo tee /etc/wireguard/private.key

شما باید یک خط خروجی کدگذاری base64 دریافت کنید که کلید خصوصی است. یک کپی از خروجی نیز در فایل /etc/wireguard/private.key برای مرجع بعدی توسط قسمت tee فرمان ذخیره می شود. کلید خصوصی خروجی را با دقت یادداشت کنید زیرا بعداً در این بخش باید آن را به فایل پیکربندی WireGuard اضافه کنید.

مرحله بعدی ایجاد کلید عمومی مربوطه است که از کلید خصوصی گرفته شده است. برای ایجاد فایل کلید عمومی از دستور زیر استفاده کنید:

sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

این دستور شامل سه فرمان جداگانه است که با استفاده از | اپراتور :

  • sudo cat /etc/wireguard/private.key: این دستور فایل کلید خصوصی را می خواند و آن را به جریان خروجی استاندارد منتقل می کند.
  • wg pubkey: فرمان دوم خروجی فرمان اول را به عنوان ورودی استاندارد خود می گیرد و برای تولید یک کلید عمومی پردازش می کند.
  • sudo tee /etc/wireguard/public.key: آخرین فرمان خروجی فرمان تولید کلید عمومی را می گیرد و آن را به پرونده ای با نام /etc/wireguard/public.key هدایت می کند.

هنگامی که فرمان را اجرا می کنید ، مجدداً یک خط خروجی کد شده base64 دریافت خواهید کرد ، که کلید عمومی سرور WireGuard شما است. آن را در جایی برای مرجع کپی کنید ، زیرا باید کلید عمومی را در هر همتایی که به سرور متصل می شود ، توزیع کنید.

مرحله 2 – انتخاب آدرس های IPv4 و IPv6

در قسمت قبل WireGuard را نصب کردید و یک جفت کلید ایجاد کردید که برای رمزگذاری ترافیک به و از سرور استفاده می شود. در این بخش ، یک فایل پیکربندی برای سرور ایجاد می کنید و WireGuard را تنظیم می کنید تا هنگام راه اندازی مجدد سرور به طور خودکار راه اندازی شود. شما همچنین آدرس های IPv4 و IPv6 خصوصی را برای استفاده با سرور WireGuard و همسالان خود تعریف خواهید کرد.

اگر قصد دارید از هر دو آدرس IPv4 و IPv6 استفاده کنید ، هر دو این بخش را دنبال کنید. در غیر این صورت ، دستورالعمل های مربوط به بخش مناسب VPN را برای نیازهای شبکه خود دنبال کنید.

مرحله 2 (الف) – انتخاب محدوده IPv4

اگر از سرور WireGuard خود با همتایان IPv4 استفاده می کنید ، سرور نیاز به طیف وسیعی از آدرس های IPv4 خصوصی دارد که برای مشتریان و رابط تونل آن استفاده می شود. شما می توانید طیف وسیعی از آدرس های IP را از بلوک های آدرس رزرو شده زیر انتخاب کنید (اگر می خواهید درباره نحوه تخصیص این بلوک ها از مشخصات RFC 1918 بیشتر بدانید):

  • 10.0.0.0 to 10.255.255.255 (10/8 prefix)
  • 172.16.0.0 to 172.31.255.255 (172.16/12 prefix)
  • 192.168.0.0 to 192.168.255.255 (192.168/16 prefix)

برای اهداف این آموزش ، از 10.8.0.0/24 به عنوان یک بلوک آدرس IP از اولین محدوده IP های رزرو شده استفاده خواهیم کرد. این محدوده تا 255 اتصال مختلف مختلف را امکان پذیر می کند ، و به طور کلی نباید آدرس های متداخل یا متناقض با سایر محدوده های IP خصوصی داشته باشد. اگر این محدوده مثال با شبکه های شما سازگار نیست ، می توانید طیف وسیعی از آدرس هایی را انتخاب کنید که با پیکربندی شبکه شما کار می کند.

سرور WireGuard از یک آدرس IP واحد برای آدرس IPv4 تونل خصوصی خود استفاده می کند. ما از 10.8.0.1/24 در اینجا استفاده می کنیم ، اما از هر آدرسی در محدوده 10.8.0.1 تا 10.8.0.255 می توان استفاده کرد. اگر از چیزی متفاوت از 10.8.0.1/24 استفاده می کنید ، آدرس IP مورد نظر خود را یادداشت کنید. شما این آدرس IPv4 را به فایل پیکربندی که در مرحله 3 تعریف کرده اید – ایجاد پیکربندی سرور WireGuard اضافه می کنید

مرحله 2 (ب) – انتخاب محدوده IPv6

اگر از WireGuard با IPv6 استفاده می کنید ، باید پیشوند آدرس منحصر به فرد IPv6 محلی منحصر به فرد را بر اساس الگوریتم RFC 4193 ایجاد کنید. آدرس هایی که با WireGuard استفاده می کنید با یک رابط مجازی تونل مرتبط خواهند بود. برای ایجاد یک پیشوند تصادفی و منحصر به فرد IPv6 در بلوک رزرو شده fd00 ::/8 آدرسهای خصوصی IPv6 ، باید چند مرحله را تکمیل کنید.

طبق RFC ، راه توصیه شده برای به دست آوردن یک پیشوند IPv6 منحصر به فرد این است که زمان روز را با یک مقدار شناسایی منحصر به فرد از یک سیستم مانند شماره سریال یا شناسه دستگاه ترکیب کنید. سپس این مقادیر هش شده و کوتاه می شوند و در نتیجه مجموعه ای از بیت ها را می توان به عنوان آدرس منحصر به فرد در بلوک IP های خصوصی fd00 ::/8 رزرو شده استفاده کرد.

برای شروع تولید محدوده IPv6 برای سرور WireGuard ، یک علامت زمان 64 بیتی را با استفاده از ابزار date با دستور زیر جمع آوری کنید:

date +%s%N

از سال 1970-01-01 00:00:00 UTC ترکیبی با هم ، عددی مانند زیر دریافت خواهید کرد ، که تعداد ثانیه ها (٪ s در دستور date) و نانو ثانیه (٪ N) است:

 

Output

1628101352127592197

مقدار را برای استفاده بعداً در این بخش در جایی ثبت کنید. در مرحله بعد ، مقدار id-machine برای سرور خود را از فایل/var/lib/dbus/machine-id کپی کنید. این شناسه مختص سیستم شماست و تا زمانی که سرور وجود دارد نباید تغییر کند.

cat /var/lib/dbus/machine-id

خروجی مانند موارد زیر را دریافت خواهید کرد:

 

/var/lib/dbus/machine-id

20086c25853947c7aeee2ca1ea849d7d

اکنون باید زمان بندی را با machine-id ترکیب کرده و مقدار حاصل را با استفاده از الگوریتم SHA-1 هش کنید. دستور از قالب زیر استفاده می کند:

printf <timestamp><machine-id> | sha1sum

دستور جایگزین را در timestamp و مقادیر هویت ماشین خود اجرا کنید:

printf 162810135212759219720086c25853947c7aeee2ca1ea849d7d | sha1sum

مقدار هش مانند موارد زیر را دریافت خواهید کرد:

 

Output

4f267c51857d6dc93a0bca107bca2f0d86fac3bc  -

توجه داشته باشید که خروجی دستور sha1sum بصورت هگزا دسیمال است ، بنابراین خروجی از دو کاراکتر برای نشان دادن یک بایت داده استفاده می کند. به عنوان مثال 4f و 26 در خروجی مثال دو بایت اول داده های هش شده هستند.

الگوریتم موجود در RFC فقط به حداقل 40 بیت یا 5 بایت خروجی هش شده نیاز دارد. از دستور cut برای چاپ 5 بایت رمزگذاری شده هگزا دسیمال از هش استفاده کنید:

printf 4f267c51857d6dc93a0bca107bca2f0d86fac3bc | cut -c 31-

آرگومان -c به دستور cut می گوید که فقط مجموعه مشخصی از کاراکترها را انتخاب کنید. آرگومان 31 به cut می گوید که همه کاراکترها را از موقعیت 31 تا انتهای خط ورودی چاپ کنید.

شما باید خروجی مانند موارد زیر را دریافت کنید:

 

Output

0d86fac3bc

در این خروجی مثال ، مجموعه بایت ها عبارتند از: 0d 86 fa c3 bc.

اکنون می توانید پیشوند شبکه IPv6 منحصر به فرد خود را با افزودن 5 بایت ایجاد شده با پیشوند fd بسازید و هر 2 بایت را با یک: colon برای خوانایی جدا کنید. از آنجا که هر زیر شبکه در پیشوند منحصر به فرد شما می تواند در مجموع 18،446،744،073،709،551،616 آدرس IPv6 احتمالی را در خود جای دهد ، می توانید برای سادگی زیر شبکه را به اندازه استاندارد 64 /محدود کنید.

با استفاده از بایت هایی که قبلاً با اندازه زیر شبکه /64 ایجاد شده بود ، پیشوند به شرح زیر خواهد بود:

 

Unique Local IPv6 Address Prefix

fd0d:86fa:c3bc::/64

این محدوده fd0d: 86fa: c3bc ::/64 چیزی است که شما برای اختصاص آدرس IP جداگانه به واسط های تونل WireGuard خود در سرور و همکاران استفاده خواهید کرد. برای اختصاص IP برای سرور ، 1 را پس از نویسه های نهایی :: اضافه کنید. آدرس حاصله fd0d: 86fa: c3bc :: 1/64 خواهد بود. همسالان می توانند از هر IP در محدوده استفاده کنند ، اما به طور معمول هر بار که یک همتا اضافه می کنید ، مقدار را به یک افزایش می دهید ، به عنوان مثال fd0d: 86fa: c3bc :: 2/64. IP را یادداشت کرده و پیکربندی WireGuard Server را در قسمت بعدی این آموزش انجام دهید.

مرحله 3 – ایجاد پیکربندی سرور WireGuard

قبل از ایجاد پیکربندی سرور WireGuard ، به اطلاعات زیر نیاز دارید:

  1. مطمئن شوید که کلید خصوصی موجود در مرحله 1 را دارید – نصب WireGuard و ایجاد یک جفت کلید.
  2. اگر از WireGuard با IPv4 استفاده می کنید ، به آدرس IP ای که در مرحله 2 (a) برای سرور انتخاب کرده اید نیاز دارید – انتخاب محدوده IPv4 ، که در این مثال 10.8.0.1/24 است.
  3. اگر از WireGuard با IPv6 استفاده می کنید ، به آدرس IP سروری که در مرحله 2 (ب) ایجاد کرده اید – انتخاب محدوده IPv6) نیاز دارید. در این مثال IP fd0d: 86fa: c3bc :: 1/64 است.

هنگامی که کلید خصوصی و آدرس IP مورد نیاز را دارید ، یک فایل پیکربندی جدید با استفاده از vi یا ویرایشگر دلخواه خود با اجرای دستور زیر ایجاد کنید:

sudo vi /etc/wireguard/wg0.conf

خطوط زیر را به فایل اضافه کنید و کلید خصوصی خود را به جای مقدار مشخص شده base64_encoded_private_key_goes_here و آدرس (های) IP در خط آدرس جایگزین کنید. اگر می خواهید WireGuard در پورت دیگری در دسترس باشد ، می توانید خط ListenPort را تغییر دهید.

i را فشار دهید تا vi وارد حالت درج شود و سپس خطوط زیر را اضافه کنید:

 

/etc/wireguard/wg0.conf

[Interface]
PrivateKey = base64_encoded_private_key_goes_here
Address = 10.8.0.1/24, fd0d:86fa:c3bc::1/64
ListenPort = 51820
SaveConfig = true

خط SaveConfig تضمین می کند که وقتی رابط WireGuard خاموش می شود ، هرگونه تغییر در فایل پیکربندی ذخیره می شود.

پس از اتمام اعمال تغییرات ، ESC و سپس: wq را فشار دهید تا تغییرات را در فایل بنویسید و خارج شوید. شما در حال حاضر پیکربندی اولیه سرور را دارید که می توانید بسته به نحوه استفاده از سرور WireGuard VPN خود ، بر اساس آن اقدام کنید.

مرحله 4 – تنظیم پیکربندی شبکه WireGuard Server

اگر از WireGuard برای اتصال همتای خود به سرور WireGuard استفاده می کنید تا فقط به خدمات روی سرور دسترسی داشته باشید ، نیازی به تکمیل این بخش ندارید. اگر می خواهید ترافیک اینترنت WireGuard Peer خود را از طریق سرور WireGuard هدایت کنید ، باید با دنبال کردن این بخش از آموزش ، ارسال IP را پیکربندی کنید.

برای پیکربندی حمل و نقل ، فایل /etc/sysctl.conf را با استفاده از vi یا ویرایشگر دلخواه خود باز کنید:

sudo vi /etc/sysctl.conf

اگر از IPv4 با WireGuard استفاده می کنید ، خط زیر را در پایین فایل اضافه کنید:

/etc/sysctl.conf

net.ipv4.ip_forward=1

اگر از IPv6 با WireGuard استفاده می کنید ، این خط را در پایین فایل اضافه کنید:

/etc/sysctl.conf

net.ipv6.conf.all.forwarding=1

اگر از IPv4 و IPv6 استفاده می کنید ، مطمئن شوید که هر دو خط را وارد کرده اید. پس از اتمام کار فایل را ذخیره و ببندید.

برای خواندن فایل و بارگذاری مقادیر جدید برای جلسه ترمینال فعلی خود ، دستور زیر را اجرا کنید:

sudo sysctl -p

 

Output

net.ipv6.conf.all.forwarding = 1
net.ipv4.ip_forward = 1

اکنون سرور WireGuard شما می تواند ترافیک ورودی را از دستگاه مجازی اترنت VPN به سرورهای دیگر و از آنجا به اینترنت عمومی هدایت کند. استفاده از این پیکربندی به شما امکان می دهد تمام ترافیک وب را از WireGuard Peer خود از طریق آدرس IP سرور خود مسیریابی کنید و آدرس IP عمومی مشتری شما به طور م hiddenثر پنهان می شود.

با این حال ، قبل از اینکه ترافیک از طریق سرور شما به درستی هدایت شود ، باید برخی از قوانین فایروال را پیکربندی کنید.

مرحله 5 – پیکربندی فایروال سرور WireGuard

در این بخش پیکربندی WireGuard Server را ویرایش می کنید تا قوانین فایروال cmd فایروال را اضافه کنید که باعث می شود ترافیک به سمت سرور و کلاینت ها به درستی مسیریابی شود. مانند بخش قبل ، اگر از WireGuard VPN خود برای اتصال دستگاه به دستگاه برای دسترسی به منابع محدود شده برای VPN خود استفاده می کنید ، این مرحله را رد کنید.

برای افزودن قوانین فایروال به سرور WireGuard ، برخی از قوانین دائمی را ایجاد می کنید که از پیکربندی صحیح سرور در هنگام راه اندازی مجدد اطمینان حاصل می کند. برای دسترسی به سرویس WireGuard در پورت UDP 51820 موارد زیر را اجرا کنید:

sudo firewall-cmd –zone=public –add-port=51820/udp –permanent

در مرحله بعد باید دستگاه wg0 را به منطقه داخلی اضافه کنید ، که به ترافیک رابط VPN اجازه می دهد تا به رابط های دیگر در سرور WireGuard برسد. اگر از سرور به عنوان دروازه VPN برای تمام ترافیک اینترنت Peer استفاده می کنید ، این تنظیم بسیار مهم است. اگر در آینده تونل های WireGuard بیشتری به سرور خود اضافه می کنید ، حتماً دستگاه های آنها را به منطقه داخلی یا مورد اطمینان نیز اضافه کنید.

برای افزودن رابط wg0 به منطقه داخلی موارد زیر را اجرا کنید:

sudo firewall-cmd –zone=internal –add-interface=wg0 –permanent

در نهایت ، اگر از سرور WireGuard به عنوان دروازه VPN استفاده می کنید ، باید یک قانون ماسکراس را به منطقه عمومی اضافه کنید. Masquerading برای بازنویسی ترافیکی که در یک رابط داخلی وارد می شود (در این مورد wg0) استفاده می شود تا به نظر برسد که مستقیماً از آدرس های عمومی IPv4 یا IPv6 سرور WireGuard سرچشمه می گیرد.

دستورات زیر را برای فعال کردن مخفی سازی ، جایگزینی در محدوده شبکه IPv4 و IPv6 خود به جای مقادیر برجسته ، اجرا کنید:

sudo firewall-cmd –zone=public –add-rich-rule=’rule family=ipv4 source address=10.8.0.0/24 masquerade’ –permanent
sudo firewall-cmd –zone=public –add-rich-rule=’rule family=ipv6 source address=fd0d:86fa:c3bc::/64 masquerade’ –permanent

اکنون فایروال را مجدداً بارگذاری کنید تا تغییرات اعمال شده و از دائمی بودن آنها اطمینان حاصل کنید:

sudo firewall-cmd –reload

اکنون می توانید وضعیت کل مناطق عمومی ، داخلی یا سایر فایروال ها را بررسی کنید تا با اجرای دستور زیر از وجود قوانین اطمینان حاصل کنید. جایگزین منطقه ای که می خواهید به جای نام عمومی برجسته شده آن را بررسی کنید:

sudo firewall-cmd –zone=public –list-all

خروجی مانند موارد زیر را دریافت خواهید کرد:

 

Output

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 51820/udp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
    rule family="ipv4" source address="10.8.0.0/24" masquerade
    rule family="ipv6" source address="fd0d:86fa:c3bc::/64" masquerade

مقادیر برجسته شده حاکی از قاعده ای است که اجازه می دهد ترافیک UDP در پورت 51820 موجود باشد و مخفی سازی برای هر یک از شبکه های ذکر شده فعال است.

همچنین می توانید با استفاده از دستور زیر تأیید کنید که قانون ارسال داخلی وجود دارد:

sudo firewall-cmd –zone=internal –list-interfaces

در صورت وجود قانون ، خروجی مشابه زیر دریافت خواهید کرد:

 

Output

wg0

سرور WireGuard شما پیکربندی شده است تا بتواند ترافیک VPN را به درستی مدیریت کند ، از جمله حمل و نقل و نقاب برای همسالان. با رعایت قوانین فایروال ، می توانید سرویس WireGuard را برای گوش دادن به ارتباطات همتا راه اندازی کنید.

مرحله 6 – راه اندازی سرور WireGuard

WireGuard را می توان پیکربندی کرد تا با استفاده از اسکریپت wg-quick خود به عنوان یک سرویس systemd اجرا شود. در حالی که می توانید به صورت دستی از دستور wg برای ایجاد تونل در هر زمان که می خواهید از VPN استفاده کنید استفاده کنید ، انجام این کار یک فرآیند دستی است که تکراری و مستعد خطا می شود. در عوض ، می توانید از systemctl برای مدیریت تونل با کمک اسکریپت wg-quick استفاده کنید.

استفاده از سرویس systemd به این معنی است که می توانید WireGuard را برای راه اندازی در هنگام راه اندازی پیکربندی کنید تا بتوانید در هر زمان که سرور در حال اجرا است به VPN خود متصل شوید. برای انجام این کار ، سرویس wg-quick را برای تونل wg0 که با افزودن آن به systemctl تعریف کرده اید ، فعال کنید:

sudo systemctl enable wg-quick@wg0.service

توجه داشته باشید که فرمان نام تونل wg0 را به عنوان بخشی از نام سرویس مشخص می کند. این نام به فایل پیکربندی /etc/wireguard/wg0.conf مربوط می شود. این رویکرد برای نامگذاری به این معنی است که می توانید هر تعداد دلخواه که از سرور خود استفاده می کنید تونل VPN جداگانه ایجاد کنید. هر تونل می تواند شامل IPv4 ، IPv6 و تنظیمات فایروال مشتری باشد.

حالا سرویس را شروع کنید:

sudo systemctl start wg-quick@wg0.service

با دستور زیر بررسی کنید که سرویس WireGuard فعال است. شما باید خروجی را فعال (در حال اجرا) ببینید:

sudo systemctl status wg-quick@wg0.service

 

Output

● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
   Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled; vendor preset: disabled)
   Active: active (exited) since Fri 2021-09-17 19:58:14 UTC; 6 days ago
     Docs: man:wg-quick(8)
           man:wg(8)
           https://www.wireguard.com/
           https://www.wireguard.com/quickstart/
           https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
           https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
 Main PID: 22924 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 11188)
   Memory: 0B
   CGroup: /system.slice/system-wg\x2dquick.slice/wg-quick@wg0.service

Sep 17 19:58:14 wg0 systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
Sep 17 19:58:14 wg0 wg-quick[22924]: [#] ip link add wg0 type wireguard
Sep 17 19:58:14 wg0 wg-quick[22924]: [#] wg setconf wg0 /dev/fd/63
Sep 17 19:58:14 wg0 wg-quick[22924]: [#] ip -4 address add 10.8.0.1/24 dev wg0
Sep 17 19:58:14 wg0 wg-quick[22924]: [#] ip -6 address add fd0d:86fa:c3bc::1/64 dev wg0
Sep 17 19:58:14 wg0 wg-quick[22924]: [#] ip link set mtu 1420 up dev wg0
Sep 17 19:58:14 wg0 systemd[1]: Started WireGuard via wg-quick(8) for wg0.

توجه کنید که چگونه خروجی دستورات ip را که برای ایجاد دستگاه مجازی wg0 استفاده می شود نشان می دهد و آدرس IPv4 و IPv6 را که به فایل پیکربندی اضافه کرده اید به آن اختصاص می دهد. اگر می خواهید پیکربندی دستی VPN را پیکربندی کنید ، می توانید از این قوانین برای عیب یابی تونل استفاده کنید ، یا با خود دستور wg.

با سرور پیکربندی و اجرا ، گام بعدی این است که دستگاه مشتری خود را به صورت WireGuard Peer پیکربندی کرده و به سرور WireGuard متصل شوید.

مرحله 7 – پیکربندی WireGuard Peer

پیکربندی یک همتای WireGuard مشابه راه اندازی WireGuard Server است. هنگامی که نرم افزار سرویس گیرنده را نصب کردید ، یک جفت کلید عمومی و خصوصی ایجاد می کنید ، در مورد آدرس IP یا آدرس برای همتای خود تصمیم می گیرید ، یک فایل پیکربندی برای همتا تعریف می کنید و سپس با استفاده از اسکریپت wg-quick تونل را راه اندازی می کنید.

با ایجاد یک جفت کلید و پیکربندی با استفاده از مراحل زیر ، می توانید هر تعداد همکار که دوست دارید به VPN خود اضافه کنید. اگر چندین VPN را به VPN اضافه می کنید ، حتماً آدرس IP خصوصی آنها را پیگیری کنید تا از برخورد جلوگیری شود.

برای پیکربندی WireGuard Peer ، مطمئن شوید که بسته WireGuard را با استفاده از دستورات dnf زیر نصب کرده اید. در اجرای همکار WireGuard:

sudo dnf install elrepo-release epel-release
sudo dnf install kmod-wireguard wireguard-tools

ایجاد جفت کلید WireGuard Peer’s Key

در مرحله بعد ، باید جفت کلید را در همتا با استفاده از مراحل مشابهی که در سرور استفاده می کنید ایجاد کنید. از دستگاه محلی یا سرور راه دور خود که به عنوان همکار عمل می کند ، دستور زیر را برای تنظیم umask روی 077 اجرا کنید:

umask 077

اکنون می توانید با استفاده از دستور زیر کلید خصوصی را برای همتا ایجاد کنید:

wg genkey | sudo tee /etc/wireguard/private.key

مجدداً یک خط خروجی کد شده base64 دریافت خواهید کرد که کلید خصوصی است. یک نسخه از خروجی نیز در /etc/wireguard/private.key ذخیره می شود. کلید خصوصی خروجی را با دقت یادداشت کنید زیرا بعداً در این بخش باید آن را به فایل پیکربندی WireGuard اضافه کنید.

سپس برای ایجاد فایل کلید عمومی از دستور زیر استفاده کنید:

sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

مجدداً یک خط خروجی کد شده base64 دریافت خواهید کرد که کلید عمومی WireGuard Peer شما است. آن را در جایی برای مرجع کپی کنید ، زیرا برای ایجاد یک اتصال رمزگذاری شده ، باید کلید عمومی را در سرور WireGuard توزیع کنید.

ایجاد فایل پیکربندی WireGuard Peer

اکنون که یک جفت کلید دارید ، می توانید یک فایل پیکربندی برای همتای خود ایجاد کنید که حاوی تمام اطلاعات مورد نیاز برای ایجاد ارتباط با سرور WireGuard باشد.

برای فایل پیکربندی به چند قطعه اطلاعات نیاز دارید:

  • base64 کلید خصوصی را که در همتا ایجاد کرده اید رمزگذاری کرد.
  • محدوده آدرس IPv4 و IPv6 که در سرور WireGuard تعریف کرده اید.
  • base64 کلید عمومی را از سرور WireGuard رمزگذاری کرد.
  • آدرس IP عمومی و شماره پورت سرور WireGuard. معمولاً این آدرس IPv4 خواهد بود ، اما اگر سرور شما دارای آدرس IPv6 است و دستگاه سرویس گیرنده شما دارای اتصال IPv6 به اینترنت است ، می توانید به جای IPv4 از این آدرس استفاده کنید.

با تمام این اطلاعات موجود ، یک فایل /etc/wireguard/wg0.conf جدید در دستگاه WireGuard Peer با استفاده از vi یا ویرایشگر دلخواه خود باز کنید:

sudo vi /etc/wireguard/wg0.conf

خطوط زیر را به فایل اضافه کنید و در صورت لزوم داده های مختلف را در قسمت های برجسته جایگزین کنید:

 

/etc/wireguard/wg0.conf

[Interface]
PrivateKey = base64_encoded_peer_private_key_goes_here
Address = 10.8.0.2/24
Address = fd0d:86fa:c3bc::2/64

[Peer]
PublicKey = base64_encoded_server_public_key_goes_here
AllowedIPs = 10.8.0.0/24, fd0d:86fa:c3bc::/64
Endpoint = 203.0.113.1:51820

 

توجه کنید که چگونه اولین خط آدرس از آدرس IPv4 از زیر شبکه 10.8.0.0/24 که قبلاً انتخاب کرده اید استفاده می کند. این آدرس IP می تواند هر چیزی در زیر شبکه باشد مگر اینکه با IP سرور متفاوت باشد. افزایش آدرس ها به میزان 1 در هر بار افزودن یک همتا به طور کلی ساده ترین راه برای تخصیص IP است.

به همین ترتیب ، توجه کنید که خط دوم آدرس چگونه از آدرس IPv6 از زیر شبکه ای که قبلاً ایجاد کرده اید استفاده می کند و آدرس سرور را یک بر یک افزایش می دهد. باز هم ، اگر تصمیم دارید از آدرس دیگری استفاده کنید ، هر IP موجود در محدوده معتبر است.

بخش قابل توجه دیگر فایل آخرین خط AllowedIPs است. این دو محدوده IPv4 و IPv6 به همکاران دستور می دهند فقط در صورتی ترافیک از طریق VPN ارسال کنند که سیستم مقصد دارای آدرس IP در هر محدوده باشد. با استفاده از دستورالعمل AllowedIPs ، می توانید VPN را بر روی همتا محدود کنید تا فقط به سایر خدمات و خدمات مشابه در VPN متصل شود ، یا می توانید تنظیماتی را انجام دهید که تمام ترافیک VPN را تونل گذاری کرده و از سرور WireGuard به عنوان دروازه استفاده کنید.

اگر فقط از IPv4 استفاده می کنید ، محدوده fd0d: 86fa: c3bc ::/64 (شامل کاما) را حذف کنید. برعکس ، اگر فقط از IPv6 استفاده می کنید ، فقط پیشوند fd0d: 86fa: c3bc ::/64 را وارد کنید و محدوده 10.8.0.0/24 IPv4 را کنار بگذارید.

در هر دو مورد ، اگر می خواهید تمام ترافیک همسالان خود را از طریق VPN ارسال کنید و از سرور WireGuard به عنوان دروازه ای برای همه ترافیک استفاده کنید ، می توانید از 0.0.0.0/0 ، که نشان دهنده کل فضای آدرس IPv4 است ، و :: /0 برای کل فضای آدرس IPv6.

(اختیاری) پیکربندی یک همتا برای مسیریابی تمام ترافیک در تونل

اگر تصمیم گرفته اید تمام ترافیک همکاران خود را از طریق تونل با استفاده از مسیرهای 0.0.0.0/0 یا ::/0 مسیریابی کنید و همتا یک سیستم از راه دور است ، باید مراحل این بخش را تکمیل کنید. اگر همتای شما یک سیستم محلی است ، بهتر است از این بخش صرف نظر کنید.

برای همسالان از راه دور که از طریق SSH یا پروتکل دیگری با استفاده از آدرس IP عمومی به آنها دسترسی پیدا می کنید ، باید برخی قوانین اضافی را به فایل wg0.conf همتا اضافه کنید. این قوانین تضمین می کند که شما هنوز می توانید از خارج از تونل به سیستم متصل شوید. در غیر این صورت ، هنگامی که تونل ایجاد می شود ، تمام ترافیکی که معمولاً در رابط شبکه عمومی انجام می شود ، به درستی جهت دور زدن رابط تونل wg0 هدایت نمی شوند و منجر به یک سیستم از راه دور می شود.

ابتدا باید آدرس IP ای را که سیستم به عنوان دروازه پیش فرض خود استفاده می کند ، تعیین کنید. دستور ip route زیر را اجرا کنید:

ip route list table main default

خروجی مانند موارد زیر را دریافت خواهید کرد:

 

Output

default via 203.0.113.1 dev eth0 proto static

به آدرس IP برجسته 203.0.113.1 درگاه برای استفاده بعدی و eth0 دستگاه توجه کنید. ممکن است نام دستگاه شما متفاوت باشد. اگر چنین است ، آن را به جای eth0 در دستورات زیر جایگزین کنید.

سپس با بررسی دستگاه با دستور نشان دادن آدرس IP آدرس عمومی سیستم را بیابید:

ip -brief address show eth0

خروجی مانند موارد زیر را دریافت خواهید کرد:

 

Output

eth0             UP             203.0.113.5/20 10.20.30.40/16 2604:a880:400:d1::3d3:6001/64 fe80::68d5:beff:feff:974c/64

در این خروجی مثال ، IP برجسته 203.0.113.5 (بدون دنباله /20) آدرس عمومی است که به دستگاه eth0 اختصاص داده شده است که باید به پیکربندی WireGuard اضافه کنید.

اکنون فایل /etc/wireguard/wg0.conf WireGuard Peer را با vi یا ویرایشگر دلخواه خود باز کنید.

sudo vi /etc/wireguard/wg0.conf

قبل از خط [Peer] ، 4 خط زیر را اضافه کنید:

PostUp = ip rule add table 200 from 203.0.113.5
PostUp = ip route add table 200 default via 203.0.113.1
PreDown = ip rule delete table 200 from 203.0.113.5
PreDown = ip route delete table 200 default via 203.0.113.1

[Peer]
. . .

این خطوط یک قانون مسیریابی سفارشی ایجاد می کنند و یک مسیر سفارشی اضافه می کنند تا اطمینان حاصل شود که ترافیک عمومی به سیستم از دروازه پیش فرض استفاده می کند.

  • PostUp = ip rule add table 200 from 203.0.113.5 – این فرمان یک قاعده ایجاد می کند که هنگام ورود IP با آدرس عمومی 203.0.113.5 سیستم ، هرگونه ورودی مسیریابی در جدول شماره 200 را بررسی می کند.
  • PostUp = ip route add table 200 default by 203.0.113.1 – این دستور اطمینان می دهد که هر ترافیکی که توسط جدول 200 پردازش می شود ، به جای رابط WireGuard ، از دروازه 203.0.113.1 برای مسیریابی استفاده می کند.
  • خطوط PreDown هنگام خاموش شدن تونل ، قانون و مسیر سفارشی را حذف می کند.

اگر تمام ترافیک همکاران خود را از طریق VPN مسیریابی می کنید ، مطمئن شوید که در sysctl و firewall-cmd درست در سرور WireGuard در مرحله 4-تنظیم پیکربندی شبکه WireGuard سرور و مرحله 5-پیکربندی فایروال سرور WireGuard پیکربندی کرده اید.

(اختیاری) پیکربندی حل کننده های DNS WireGuard Peer

اگر از سرور WireGuard به عنوان یک دروازه VPN برای همه ترافیک همکاران خود استفاده می کنید ، باید خطی را به بخش [رابط] اضافه کنید که حل کننده های DNS را مشخص می کند. اگر این تنظیم را اضافه نکنید ، ممکن است درخواست های DNS شما توسط VPN محافظت نشود ، یا ممکن است به ارائه دهنده خدمات اینترنت شما یا سایر اشخاص ثالث فاش شود.

اگر فقط از WireGuard برای دسترسی به منابع در شبکه VPN یا پیکربندی peer-to-peer استفاده می کنید ، می توانید این بخش را رد کنید.

برای افزودن حل کننده های DNS به پیکربندی همکار خود ، ابتدا تعیین کنید سرور WireGuard شما از کدام سرورهای DNS استفاده می کند. دستور زیر را در سرور WireGuard اجرا کنید ، اگر نام دستگاه اترنت خود را به جای eth0 جایگزین کنید اگر متفاوت از این مثال باشد:

cat /etc/resolv.conf

شما باید خروجی مانند موارد زیر را دریافت کنید:

 

Output

; Created by cloud-init on instance boot automatically, do not edit.
;
nameserver 67.207.67.2
nameserver 67.207.67.3

آدرس های IP خروجی راه حل های DNS هستند که سرور از آنها استفاده می کند. بسته به نیاز خود می توانید از همه یا همه آنها یا فقط IPv4 یا IPv6 استفاده کنید. حل کننده هایی را که استفاده می کنید یادداشت کنید.

در مرحله بعد باید حل کننده های انتخابی خود را به فایل پیکربندی WireGuard Peer اضافه کنید. دوباره به WireGuard Peer برگردید ، فایل /etc/wireguard/wg0.conf را با استفاده از vi یا ویرایشگر دلخواه باز کنید:

sudo vi /etc/wireguard/wg0.conf

قبل از خط [Peer] موارد زیر را اضافه کنید:

DNS = 67.207.67.2 67.207.67.3

[Peer]
. . .

باز هم ، بسته به اولویت یا الزامات شما برای IPv4 و IPv6 ، می توانید لیست را با توجه به نیاز خود ویرایش کنید.

در مرحله بعد ، سرویس حل شده با سیستم را در Peer فعال و راه اندازی کنید تا وقتی تونل ایجاد شد ، حل کننده های DNS Peer به روز شود:

sudo systemctl enable systemd-resolved

اگر Rocky Linux و احتمالاً سایر توزیع های مشتق از RedHat مانند CentOS یا Fedora در حال اجرا هستند ، باید سیستم همتای خود را در این مرحله راه اندازی مجدد کنید. اگر آن را راه اندازی مجدد نکنید ، فایل /etc/resolv.conf هنگام راه اندازی تونل به دلیل اشکالی در برنامه های systemd-حل شده یا ابزارهای حفاظتی ، مجوزهای صحیح را تنظیم نمی کند. WireGuard Peer را با دستور زیر راه اندازی مجدد کنید:

sudo reboot

با وجود همه این تنظیمات حل کننده DNS و راه اندازی مجدد همکار ، اکنون آماده هستید که کلید عمومی همکار را به سرور اضافه کنید و سپس تونل WireGuard را روی همتا راه اندازی کنید.

مرحله 8 – افزودن کلید عمومی Peer به سرور WireGuard

قبل از اتصال همتا به سرور ، مهم است که کلید عمومی همتا را به سرور WireGuard اضافه کنید. این مرحله تضمین می کند که می توانید ترافیک را از طریق VPN متصل و مسیریابی کنید. بدون اتمام این مرحله ، سرور WireGuard به همکاران اجازه ارسال یا دریافت ترافیک از طریق تونل را نمی دهد.

با اجرای موارد زیر ، مطمئن شوید که نسخه ای از کلید عمومی کد شده base64 را برای WireGuard Peer در اختیار دارید:

sudo cat /etc/wireguard/public.key

 

Output

PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg=

حالا وارد سرور WireGuard شده و دستور زیر را اجرا کنید:

sudo wg set wg0 peer PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg= allowed-ips 10.8.0.2,fd0d:86fa:c3bc::2

توجه داشته باشید که قسمت مجاز-ips فرمان ، لیستی از آدرس های IPv4 و IPv6 را با کاما جدا می کند. اگر می خواهید آدرس IP را که یک همتا می تواند به خود اختصاص دهد محدود کنید یا اگر همسالان شما می توانند از هر آدرس IP در محدوده VPN استفاده کنند ، می توانید IP های فردی را تعیین کنید. همچنین توجه داشته باشید که هیچ یک از همسالان نمی توانند تنظیمات مجاز ips یکسانی داشته باشند.

اگر می خواهید ips مجاز برای یک همکار موجود را به روز کنید ، می توانید دوباره همان فرمان را اجرا کنید ، اما آدرس IP را تغییر دهید. چندین آدرس IP پشتیبانی می شود. به عنوان مثال ، برای تغییر WireGuard Peer که به تازگی اضافه کرده اید و IP ای مانند 10.8.0.100 را به IP های 10.8.0.2 و fd0d: 86fa: c3bc :: 2 موجود اضافه می کنید ، موارد زیر را اجرا کنید:

sudo wg set wg0 peer PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg= allowed-ips 10.8.0.2,10.8.0.100,fd0d:86fa:c3bc::2

پس از اجرای دستور افزودن همتا ، وضعیت تونل را روی سرور با استفاده از دستور wg بررسی کنید:

sudo wg

 

Output

interface: wg0
 public key: U9uE2kb/nrrzsEU58GD3pKFU3TLYDMCbetIsnV8eeFE=
 private key: (hidden)
 listening port: 51820

peer: PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg=
 allowed ips: 10.8.0.2/32, fd0d:86fa:c3bc::/128

توجه کنید که چگونه خط همتا کلید عمومی WireGuard Peer و آدرس های IP یا محدوده آدرس هایی را نشان می دهد که مجاز است از آنها برای اختصاص IP خود استفاده کند.

اکنون که پارامترهای اتصال همتا را روی سرور تعریف کرده اید ، مرحله بعدی این است که تونل را روی همتا راه اندازی کنید.

مرحله 9 – اتصال WireGuard Peer به Tunnel

اکنون که سرور و همکار شما به گونه ای پیکربندی شده اند که از انتخاب IPv4 ، IPv6 ، ارسال بسته ها و وضوح DNS پشتیبانی می کنند ، زمان آن رسیده است که همتا را به تونل VPN متصل کنید.

از آنجا که ممکن است فقط بخواهید VPN برای موارد خاص استفاده شود ، ما از دستور wg-quick برای ایجاد اتصال بصورت دستی استفاده می کنیم. اگر می خواهید شروع به کار تونل را مانند سرور انجام دهید ، مراحل زیر را در مرحله 6 دنبال کنید-به جای استفاده از دستور wq-quick ، بخش WireGuard Server را راه اندازی کنید.

برای شروع تونل ، موارد زیر را در WireGuard Peer اجرا کنید:

sudo wg-quick up wg0

خروجی مانند موارد زیر را دریافت خواهید کرد:

 

Output

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.8.0.2/24 dev wg0
[#] ip -6 address add fd0d:86fa:c3bc::2/64 dev wg0
[#] ip link set mtu 1420 up dev wg0

آدرس های IPv4 و IPv6 برجسته ای را که به همتای خود اختصاص داده اید ، اضافه کنید.

اگر AllowedIPs را روی همتا روی 0.0.0.0/0 و ::/0 تنظیم کنید (یا از محدوده هایی غیر از محدوده هایی که برای VPN انتخاب کرده اید استفاده کنید) ، خروجی شما شبیه موارد زیر خواهد بود:

 

Output

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.8.0.2/24 dev wg0
[#] ip -6 address add fd0d:86fa:c3bc::2/64 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] mount `67.207.67.2' /etc/resolv.conf
[#] wg set wg0 fwmark 51820
[#] ip -6 route add ::/0 dev wg0 table 51820
[#] ip -6 rule add not fwmark 51820 table 51820
[#] ip -6 rule add table main suppress_prefixlength 0
[#] nft -f /dev/fd/63
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] nft -f /dev/fd/63
[#] ip rule add table 200 from 203.0.113.5
[#] ip route add table 200 default via 203.0.113.1

در این مثال ، به مسیرهای برجسته شده ای که فرمان اضافه کرده و مربوط به AllowedIPs در پیکربندی همتا است توجه کنید.

در مرحله بعد ، با استفاده از ping مقداری ترافیک در رابط تونل ایجاد کنید تا یک بسته ICMP (که در دستورات زیر با آرگومان -c 1 مشخص شده است) به سرور WireGuard نشان داده شود:

ping -c 1 10.8.0.1

اگر تمام ترافیک را از طریق VPN مسیریابی می کنید ، می توانید به جای آن از یکی از سرورهای CloudFlare استفاده کنید:

ping -c 1 1.1.1.1

اکنون با استفاده از دستور wg وضعیت تونل را روی همتا بررسی کنید:

sudo wg

 

Output

interface: wg0
 public key: PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg=
 private key: (hidden)
 listening port: 49338
 fwmark: 0xca6c

peer: U9uE2kb/nrrzsEU58GD3pKFU3TLYDMCbetIsnV8eeFE=
 endpoint: 203.0.113.1:51820
 allowed ips: 10.8.0.0/24, fd0d:86fa:c3bc::/64
 latest handshake: 1 second ago
 transfer: 6.50 KiB received, 15.41 KiB sent

همچنین می توانید وضعیت سرور را دوباره بررسی کنید و خروجی مشابهی دریافت خواهید کرد.

با استفاده از دستورات مسیر ip و مسیر ip -6 تأیید کنید که همتای شما از VPN استفاده می کند. اگر از VPN به عنوان دروازه ای برای همه ترافیک اینترنت خود استفاده می کنید ، بررسی کنید که کدام رابط برای ترافیک مقصد 1.1.1.1 CloudFlare و 2606: 4700: 4700 :: 1111 DNS وضوح مورد استفاده قرار می گیرد.

ip route get 1.1.1.1

 

Output

1.1.1.1 dev wg0 table 51820 src 10.8.0.2 uid 1000
   cache

توجه داشته باشید که از دستگاه wg0 و آدرس IPv4 10.8.0.2 که به همتای خود اختصاص داده اید استفاده می شود. به همین ترتیب ، اگر از IPv6 استفاده می کنید ، موارد زیر را اجرا کنید:

ip -6 route get 2606:4700:4700::1111

 

Output

2606:4700:4700::1111 dev wg0 table 51820 src fd0d:86fa:c3bc::2 metric 1024 pref medium

دوباره به رابط wg0 و آدرس IPv6 fd0d: 86fa: c3bc :: 2 که به همتای خود اختصاص داده اید توجه کنید.

اگر مرورگر همتای شما نصب شده است ، همچنین می توانید از ipleak.net و ipv6-test.com دیدن کنید تا تأیید کنید که همتای شما ترافیک خود را از طریق VPN مسیریابی می کند.

هنگامی که آماده قطع ارتباط VPN با همکار هستید ، از دستور wg-quick استفاده کنید:

sudo wg-quick down wg0

خروجی مشابه زیر دریافت خواهید کرد که نشان می دهد تونل VPN خاموش است:

 

Output

[#] ip link delete dev wg0

اگر AllowedIPs را روی همتا روی 0.0.0.0/0 و ::/0 تنظیم کنید (یا از محدوده هایی غیر از محدوده هایی که برای VPN انتخاب کرده اید استفاده کنید) ، خروجی شما شبیه موارد زیر خواهد بود:

 

Output

[#] ip rule delete table 200 from 137.184.109.48
[#] ip route delete table 200 default via 137.184.96.1
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip -6 rule delete table 51820
[#] ip -6 rule delete table main suppress_prefixlength 0
[#] ip link delete dev wg0
[#] umount /etc/resolv.conf
[#] nft -f /dev/fd/63

برای اتصال مجدد به VPN ، دستور wg-quick up wg0 را دوباره روی همتا اجرا کنید. اگر می خواهید پیکربندی همتا را از سرور WireGuard حذف کنید ، می توانید دستور زیر را اجرا کنید ، مطمئن باشید که کلید عمومی صحیح را برای همتایی که می خواهید حذف کنید جایگزین کنید:

sudo wg set wg0 peer PeURxj4Q75RaVhBKkRTpNsBPiPSGb5oQijgJsTa29hg= remove

به طور معمول فقط در صورت عدم وجود همتای دیگر ، یا کلیدهای رمزگذاری آن به خطر افتاده یا تغییر کرده است ، باید پیکربندی همتا را حذف کنید. در غیر این صورت بهتر است پیکربندی را در محل خود بگذارید تا همکار بتواند مجدداً به VPN متصل شود بدون اینکه لازم باشد هر بار کلید و ips مجاز آن را اضافه کنید.

نتیجه

در این آموزش شما بسته و ابزار WireGuard را روی هر دو سیستم سرور و سرویس گیرنده Rocky Linux 8 نصب کرده اید. شما قوانین فایروال را برای WireGuard تنظیم کرده و تنظیمات هسته را پیکربندی کرده اید تا بتوانید با استفاده از دستور sysctl روی سرور ، ارسال بسته را انجام دهید. شما نحوه تولید کلیدهای رمزگذاری خصوصی و عمومی WireGuard و نحوه پیکربندی سرور و همکاران (یا همتا) برای اتصال به یکدیگر را آموختید.

اگر شبکه شما از IPv6 استفاده می کند ، همچنین آموخته اید که چگونه یک محدوده آدرس محلی منحصر به فرد برای استفاده از اتصالات همتا ایجاد کنید. در نهایت ، شما نحوه محدود کردن میزان ترافیک VPN را با محدود کردن پیشوندهای شبکه که همکار می تواند استفاده کند ، و همچنین نحوه استفاده از سرور WireGuard به عنوان یک دروازه VPN برای رسیدگی به تمام ترافیک اینترنت برای همسالان یاد گرفتید.

 

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه ایجاد افزونه منبع سفارشی در Gatsby

ورود به سایت

معرفی

در ایجاد یک وب سایت یا برنامه ، اغلب یکی از سخت ترین کارها این است که داده ها را از منابع متعدد جمع آوری کرده و آنها را در یک خروجی یکنواخت جمع آوری کنید. یک راه رایج برای حل این مشکل استفاده از سیستم های ساخت کاملاً متفاوت برای قسمت های مختلف یک سایت است ، اما این امر گاهی پیچیدگی را افزایش می دهد در حالی که دستیابی به یکنواختی را دشوارتر می کند. اینجاست که Gatsby ، یک تولید کننده سایت استاتیک مبتنی بر داده (SSG) می تواند راه حلی ارائه دهد.

یکی از اهداف اصلی Gatsby حل این مشکل برای توسعه دهندگان است و افزونه های منبع اصلی ترین راه برای این کار هستند. افزونه منبع مجموعه ای از کد است که داده ها را از یک منبع معین وارد اکوسیستم Gatsby می کند. منابع می توانند از سیستم فایل محلی مانند فایلهای Markdown ، پایگاه های داده ، فیدهای داده منتشر شده یا حتی منابع داده از راه دور کاملاً پویا مانند API ها باشند.

در این آموزش ، شما پلاگین منبع سفارشی خود را ایجاد می کنید تا داده های جدید را از یک API دنیای واقعی به Gatsby وارد کنید. همچنین داده ها را فرمت می کنید تا در سراسر Gatsby به آنها دسترسی داشته باشید و در پایان آموزش ، یک پروژه کاری داشته باشید که HTML ایستا را از منبع داده پویای جدید شما ایجاد می کند.

پیش نیازها

قبل از شروع کار ، چند مورد را که لازم دارید در اینجا آورده ایم:

  • نصب محلی Node.js برای اجرای Gatsby و ایجاد سایت شما. روش نصب بر اساس سیستم عامل متفاوت است ، اما vpsgol دارای راهنمای Ubuntu 20.04 و macOS است و همیشه می توانید آخرین نسخه را در صفحه بارگیری رسمی Node.js پیدا کنید.
  • آشنایی با جاوا اسکریپت برای کار در Gatsby. زبان جاوا اسکریپت یک مبحث گسترده است ، اما نقطه شروع خوب ما نحوه کدگذاری در سری جاوا اسکریپت است.
  • آشنایی با API های وب ، Node.js و JSON.
  • یک پروژه جدید Gatsby، داربست از gatsby-starter-default. برای برآوردن این نیاز و ایجاد پروژه جدید Gatsbyاز ابتدا ، می توانید به مرحله 1 آموزش نحوه راه اندازی اولین وب سایت Gatsby مراجعه کنید.
  • اگر می خواهید رابط کاربری (UI) پست های خود را فراتر از آنچه در این آموزش آمده است سفارشی کنید ، با React و JSX و همچنین عناصر HTML آشنا باشید.

این آموزش روی Node.js v14.16.1 ، npm v6.14.12 ، Gatsby v3.13.0 و node-fetch v2.6.2 آزمایش شده است.

مرحله 1 – فایل های داربست و نصب وابستگی ها

هنگام ساختن چیزی ، اولین قدم این است که ابزارها و قطعات خود را مرتب کنید. در این مرحله ، با ایجاد ساختار فایل لازم و نصب وابستگی هایی که کد شما بر آن تکیه می کند ، بلوک های اولیه افزونه منبع خود را در محل قرار می دهید.

از آنجا که این یک افزونه محلی خواهد بود ، یک دایرکتوری در پروژه Gatsby خود ایجاد کنید تا کد منبع افزونه را در زیر پوشه افزونه های سطح ریشه نگه دارید. می توانید این کار را با ایجاد پوشه به صورت دستی در مرورگر فایل خود یا از خط فرمان در ریشه پروژه با دستور mkdir انجام دهید:

mkdir -p plugins/my-custom-source-plugin

در مرحله بعد ، باید یک فایل package.json ایجاد کنید تا این دایرکتوری را به عنوان بسته Node.js با وابستگی های خاص خود علامت گذاری کنید. برای ایجاد این فایل و پیش پر کردن برخی از فیلدهای مورد نیاز ، از دستور زیر استفاده کنید:

cd plugins/my-custom-source-plugin
npm init -y

این دستور به پوشه افزونه تازه ایجاد شده شما منتقل می شود و سپس از npm init برای راه اندازی مجدد یک بسته جدید استفاده می کند. پرچم -y برخی از سوالات بی ربط به این پروژه را رد می کند و فایل package.json را با حداقل مقادیر مورد نیاز پر می کند.

اکنون که package.json وجود دارد ، می توانید وابستگی هایی را به افزونه خود اضافه کنید که کدگذاری عملکرد را آسان تر می کند. پیش بروید و تنها وابستگی اضافی مورد نیاز خود را در این آموزش ، node-fetch ، با استفاده از دستور زیر نصب کنید:

npm install node-fetch@^2

در نهایت ، فایل gatsby-node.js را ایجاد کنید که در نهایت کد اصلی افزونه منبع را در اختیار داشته باشد:

touch gatsby-node.js

اکنون که ساختار فایل را برای پشتیبانی از افزونه خود ایجاد کرده اید و وابستگی های اولیه را نصب کرده اید ، به دستورالعمل هایی برای یافتن و بارگیری افزونه خود به gatsby ادامه می دهید.

مرحله 2 – بارگیری و پیکربندی افزونه

مانند هر افزونه یا تم Gatsby ، Gatsby باید در مورد نحوه بارگیری افزونه از کجا آموزش داده شود. برای انجام این کار ، فایل پیکربندی اصلی Gatsby را ویرایش می کنید gatsby-config.js ، که در ریشه پروژه Gatsby شما قرار دارد. فایل را در ویرایشگر دلخواه خود باز کنید و خط برجسته زیر را اضافه کنید:

gatsby-config.js

module.exports = {
...
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-image`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `my-custom-source-plugin`,
    `gatsby-transformer-sharp`,
...

از آنجا که کد منبع افزونه شما در فهرست افزونه ها وجود دارد ، تنها چیزی که برای بارگیری Gatsby لازم است این است که به نام زیر شاخه ای که در آن پوشه یافت می شود ، وارد شود. افزونه شما نیز در حال حاضر هیچ گزینه ای را انتخاب نمی کند ، بنابراین نیازی به ارسال شیء گزینه به آن در بلوک پیکربندی Gatsby نیست.

gatsby-config.js را ذخیره کرده و از فایل خارج شوید.

اکنون Gatsby را طوری پیکربندی کرده اید که افزونه منبع سفارشی شما را بارگذاری کند و همچنین به آن دقیقاً گفته اید که کجا باید کد منبع را پیدا کند. در مرحله بعد ، این کد منبع را برای کشیدن داده ها در زمان اجرا Node.js از منبع راه دور سفارشی خود ایجاد می کنید.

مرحله 3 – کشیدن داده های خام به Node.js

در مرحله قبل ، شما Gatsbyرا برای بارگیری و اجرای کد افزونه منبع سفارشی خود پیکربندی کرده اید ، اما برای انجام وظیفه وارد کردن داده های جدید به اکوسیستم Gatsby، هنوز باید این کد را ایجاد کنید. در این مرحله ، کدی را که این کار را انجام می دهد ، می نویسید ، داده های از راه دور را از طریق node-fetch واکشی کرده و برای استفاده در مراحل بعدی آماده می کنید.

افزونه های منبع می توانند تقریباً از هر جایی ، محلی یا از راه دور ، داده ها را جمع آوری کنند ، اما در این آموزش افزونه منبع شما به طور خاص عناوین و گزیده ای از دسته کتاب های برنامه نویسی رایانه ای در ویکی پدیا را از طریق API عمومی خود می کشد.

فایل my-custom-source-plugin/gatsby-node.js خود را در فهرست افزونه ها باز کرده و کد زیر را اضافه کنید:

plugins/my-custom-source-plugin/gatsby-node.js

const fetch = require('node-fetch').default

/**
 * Fetch a list of computer books from Wikipedia, with excerpts
 */
async function getWikiProgrammingBooks() {
  const BASE_ENDPOINT = "https://en.wikipedia.org/w/api.php?action=query&format=json&utf8=1&redirects=1";

  // Get list of books
  const listEndpoint = new URL(BASE_ENDPOINT);
  listEndpoint.searchParams.append('list', 'categorymembers');
  listEndpoint.searchParams.append("cmtitle", "Category:Computer_programming_books");
  listEndpoint.searchParams.append("cmlimit", "10");
  const listResults = await (await fetch(listEndpoint.toString())).json();


  // Extract out the page IDs from the list
  const pageIds = listResults.query.categorymembers.map((listing) => listing.pageid);

  // Fetch details for page IDs
  const extractEndpoint = new URL(BASE_ENDPOINT);
  extractEndpoint.searchParams.append("pageids", pageIds.join("|"));
  extractEndpoint.searchParams.append("prop", "extracts|info");
  extractEndpoint.searchParams.append("exintro", "");
  extractEndpoint.searchParams.append("explaintext", "");
  extractEndpoint.searchParams.append("inprop", "url");

  const bookResult = await (await fetch(extractEndpoint.toString())).json();

  return Object.values(bookResult.query.pages);
}

در این کد ، شما یک تابع قابل استفاده مجدد ایجاد کرده اید که می تواند برای بازگرداندن لیستی از کتابهای برنامه نویسی کامپیوتر ، به همراه شناسه های صفحه آنها (یک شناسه منحصر به فرد در ویکی پدیا) و گزیده ها/عصاره ها فراخوانی شود. در قسمت اول تابع ، URL API مناسب را ایجاد می کنید تا بتوانید لیست اولیه عناوین و شناسه های مربوط به یک دسته خاص (کتابهای برنامه نویسی کامپیوتر) را برای استفاده از آن استفاده کنید. از سازنده URL و رابط برای خواندن و مدیریت تغییرات پرس و جو استفاده می شود.

شما از روش واکشی از node-fetch برای درخواست GET به URL ساخته شده استفاده می کنید ، که لیستی از عناوین کتاب با شناسه های آنها را برمی گرداند. سپس این پاسخ به آرایه ای از مقادیر pageid تبدیل می شود ، سپس برای پرس و جو مجدد API ویکی پدیا استفاده می شود ، این بار درخواست استخراج و اطلاعات متای تولید شده برای شناسه صفحه داده شده. شناسه های صفحه با کاراکتر پیپ (|) به هم متصل می شوند ، زیرا API ویکی پدیا از این قالب برای پذیرش چندین شناسه از طریق یک مقدار رشته استفاده می کند.

سرانجام ، از آنجا که نتایج گزیده های صفحه به عنوان یک شیء باز می گردند و هر کتابی در شناسه خود به عنوان کلید درج شده است ، از Object.values ​​() برای حذف کلید شناسه صفحه و تبدیل نتایج به یک آرایه قبل از بازگشت آنها استفاده می کنید.

اگر خروجی این تابع را وارد کنید ، چیزی شبیه به این خواهد بود:

[
  {
    "pageid": 379671,
    "ns": 0,
    "title": "The C Programming Language",
    "extract": "The C Programming Language (sometimes termed K&R, after its authors' initials) is a computer programming book written by Brian Kernighan and Dennis Ritchie...",
    "fullurl": "https://en.wikipedia.org/wiki/The_C_Programming_Language",
    ...
  },
  ...
]

مطمئن شوید که تغییرات خود را ذخیره می کنید ، اما این فایل را باز نگه دارید زیرا در مرحله بعد کد بیشتری به آن اضافه می کنید.

در این مرحله از node-fetch برای بازیابی محتوای منبع از راه دور و نمایش آن در فایل gatsby-node.js استفاده کردید. در مرحله بعد ، محتوا را عادی می کنید زیرا از آن برای ایجاد گره های جدید Gatsby برای استفاده در کل پروژه Gatsby استفاده می کنید.

مرحله 4 – عادی سازی داده ها و ایجاد گره ها

واکشی محتوای از راه دور و آوردن آن در gatsby-node.js در مرحله قبل به این معنی نیست که اکنون در سراسر Gatsbyقابل دسترسی است. به منظور به اشتراک گذاری داده ها به صورت جهانی ، Gatsby از مفهوم گره ها استفاده می کند ، که در یک لایه داده GraphQL یکپارچه به اشتراک گذاشته می شوند. در این مرحله ، شما این گره ها را ایجاد می کنید و محتوای جدید خود را برای مطابقت قالب بندی می کنید.

اگرچه اکنون می توانید با فراخوانی getWikiProgrammingBooks () نتایج ویکی پدیا را بازیابی کرده و به آنها دسترسی پیدا کنید ، اما برای ادغام این کد با سیستم گره Gatsby، هنوز باید کد را اضافه کنید. در همان فایل gatsby-node.js مرحله قبل ، این بلوک جدید کد را برای مدیریت تولید گره ها اضافه کنید:

plugins/my-custom-source-plugin/gatsby-node.js

const fetch = require('node-fetch').default

...

exports.sourceNodes = async ({ actions, createContentDigest, createNodeId }) => {
  // Arbitrary node type constant
  const BOOK_TYPE = 'BookWikiPage';

  // Get books
  const bookResults = await getWikiProgrammingBooks();

  // Convert raw book results to nodes
  for (const book of bookResults) {
    actions.createNode({
      ...book,
      id: createNodeId(`${BOOK_TYPE}-${book.pageid}`),
      parent: null,
      children: [],
      internal: {
        type: BOOK_TYPE,
        contentDigest: createContentDigest(book)
      }
    })
  }
};

در این بلوک کد ، شما در حال تکرار هر کتابی هستید که توسط getWikiProgrammingBooks بازگردانده می شود و یک گره Gatsbyبرای آن از طریق روش createNode ایجاد می کنید. هر ویژگی و مقداری که به createNode منتقل می شود دارای اهمیت است و ارزش توجه دارد:

  • … کتاب برای گسترش جفت های کلید-مقدار از شی API ویکی پدیا در گره Gatsby که ایجاد می کنید استفاده می شود. این بدان معناست که بعداً می توانید به node.title دسترسی پیدا کنید ، زیرا از book.title کپی می شود.
  • شناسه یک ارزش جهانی منحصر به فرد در داخل Gatsby است. برای اینکه شناسه هر کتاب را در افزونه خود منحصر به فرد کنید ، باید نوع کتاب را با شناسه صفحه ویکی پدیا ترکیب کرده و یک رشته شناسه تشکیل دهید. با این حال ، از آنجا که نمی توانید مطمئن شوید سایر افزونه ها از چه شناسه هایی استفاده می کنند ، از بهترین روش ارسال شناسه خود برای ایجادNodeId استفاده کرده اید ، که یک تابع کمکی Gatsby است و تضمین می کند که شناسه به چیزی در سطح جهانی تبدیل شده است.
  • والد فیلدی است که می توان از آن برای اتصال گره شما به دیگری از طریق شناسه استفاده کرد و این گره را در کودکی علامت گذاری کرد. از آنجا که هر کتاب موجودیت خاص خود است و به گره های دیگر متصل نیست ، این را به عنوان خالی گذاشته اید ، به این معنی که والد ندارد.
  • کودکان به عنوان راهی برای پیوند گره ها شبیه به والدین هستند ، اما آرایه ای از شناسه ها را می گیرد. از آنجا که هر کتاب فرزندی ندارد ، آرایه را خالی گذاشته اید.
  • داخلی شیئی است که زمینه های بسیار ویژه سیستم مدیریت گره داخلی Gatsby و سایر افزونه ها را با هم گروه بندی می کند. این فقط می تواند شامل فیلدهای رسمی باشد ، به همین دلیل است که شما شیء کتاب را در آن پخش نکرده اید.
  • type یک رشته منحصر به فرد در سطح جهان است که نوع گره ای را که ایجاد می کنید توصیف می کند و بعداً هنگام درخواست گره ها از طریق GraphQL مورد استفاده قرار می گیرد.
  • contentDigest یک رشته هش است که از محتویات گره و ابزار کمکی Gatsby createContentDigest ساخته شده است. این فیلد به Gatsby کمک می کند تا تشخیص دهد که یک گره چه زمانی تغییر کرده است ، زیرا در صورت اصلاح هرگونه ویژگی شیء کتاب ، رشته هش تغییر می کند.

شما به تازگی کدی را اضافه کرده اید که محتوای منبع شما را می گیرد و با آن گره های جدید Gatsby ایجاد می کند و آنها را در محیط Gatsby به اشتراک می گذارد. در مرحله بعد ، شما تأیید می کنید که این گره ها در لایه داده GraphQL ظاهر می شوند و می توان آنها را پرس و جو کرد.

مرحله 5 – (اختیاری) بازرسی خروجی گره با API GraphQL

در حال حاضر ، شما محتوای منبع خود را به داخل Gatsby کشانده اید و از آن برای ایجاد گره های جدید استفاده کرده اید. به عنوان جایگزینی برای اشکال زدایی دستی با نقاط شکست یا دستورات ورود به سیستم ، در این مرحله از GraphQL IDE تعاملی برای تأیید اینکه این گره های جدید در حال ایجاد شدن هستند و می توانند با API GraphQL پرس و جو شوند ، استفاده خواهید کرد.

پیش بروید و با اجرای این دستور از ریشه پروژه Gatsby خود ، سرور توسعه محلی خود را راه اندازی کنید:

npm run develop

علاوه بر راه اندازی نسخه زنده سایت Gatsby ، فرمان develop همچنین سرور GraphQL و IDE محلی را نیز نشان می دهد. برای تأیید اینکه کد شما در gatsby-node.js تمام گره های کتاب را ایجاد می کند ، از این پرس و جو GraphQL برای دریافت عناوین کتاب ، شناسه های صفحه و شناسه های Gatsby استفاده خواهید کرد:

{
  allBookWikiPage {
    edges {
      node {
        title
        pageid
        id
      }
    }
  }
}

برای اجرای این پرس و جو ، یا GraphQL IDE تعاملی را در localhost باز کنید: 8000/___ graphql و قبل از اجرا پرس و جو را در سمت چپ قرار دهید یا از طریق cURL آن را پرس و جو کنید.

curl –location –request POST ‘http://localhost:8000/___graphql’ \
–header ‘Content-Type: application/json’ \
–data-raw ‘{
“query”: “{ allBookWikiPage { edges { node { title pageid id } } } }”
}’

پاسخ JSON چیزی شبیه به این خواهد بود:

{
  "data": {
    "allBookWikiPage": {
      "edges": [
        {
          "node": {
            "title": "The C Programming Language",
            "pageid": 379671,
            "id": "818771ca-40aa-5cfd-b9e7-fddff093d5ec"
          }
        },
        ...
      ]
    }
  },
  "extensions": {}
}

پس از تأیید اینکه گره های منبع سفارشی جدید شما ایجاد شده اند و در لایه داده GraphQL قابل دسترسی هستند ، مرحله بعدی استفاده از آنها برای ایجاد محتوای قابل مشاهده برای بازدیدکنندگان سایت یا برنامه شما است.

مرحله 6 – (اختیاری) ایجاد صفحات بر اساس گره ها

تا کنون ، تمام مراحل قبلی بر ایجاد گره های داخلی Gatsby متمرکز شده است ، از جمله آخرین مرحله تأیید ایجاد و توانایی بازیابی آنها. با این حال ، این گره ها فقط برای کد در حال اجرا در پروژه Gatsby شما قابل مشاهده هستند ، نه برای بازدیدکنندگان از سایت یا برنامه شما. در این مرحله ، شما یک فایل قالب صفحه React اضافه کرده و آن را به گره های خود وصل می کنید تا محتوای افزونه منبع شما به صفحات وب واقعی واقعی تبدیل شود.

روش های مختلفی برای ایجاد صفحات بر اساس گره های Gatsby وجود دارد ، اما برای این آموزش شما از API File System Route استفاده خواهید کرد ، که صفحات را بر اساس نحو نام فایل خاص ایجاد می کند.

ابتدا یک فایل خالی در src/pages با نام فایل {BookWikiPage.title} .js ایجاد کنید. مهاربندهای پیچ دار به Gatsby می گویند که نام فایل از API مسیر سیستم استفاده می کند و در داخل براکت ها ، BookWikiPage.title به Gatsby می گوید که برای هر عنوان کتاب منحصر به فرد صفحه ای ایجاد کند. توجه داشته باشید که دیگر روی فایلهای موجود در فهرست افزونه ها کار نمی کنید ، اما اکنون در داخل پروژه اصلی Gatsby کار می کنید.

در مرحله بعد ، کدی را به آن فایل اضافه کنید که گره کتاب را گرفته و آن را به عنوان یک صفحه وب نمایش می دهد:

import { graphql } from "gatsby";
import * as React from "react";
import Layout from "../components/layout";
import Seo from "../components/seo";

export default function BookPageTemplate({ data: { bookWikiPage } }) {
  const { title, extract, fullurl } = bookWikiPage;
  return (
    <Layout>
      <Seo title={title} />
      <h1>{title}</h1>
      <blockquote>{extract}</blockquote>

      <i>This article uses material from the Wikipedia article <a href={fullurl} target="_blank" rel="noreferrer">"{title}"</a>, which is released under the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share-Alike License 3.0</a>.</i>
    </Layout>
  );
}

export const pageQuery = graphql`
  query ($id: String!) {
    bookWikiPage(id: { eq: $id }) {
      title
      extract
      fullurl
    }
  }
`;

در انتهای کد شما یک متغیر صادر شده به نام pageQuery وجود دارد که از تگ Gatsby GraphQL استفاده می کند. Gatsby پرس و جو GraphQL را که از آن استفاده می کند ، ارزیابی کرده و نتایج را به تابع BookPageTemplate منتقل می کند.

تابع BookPageTemplate ، که جزء React است ، سپس نتایج پرس و جو GraphQL را گرفته و با جاسازی مقادیر در JSX که برمی گرداند ، آنها را به عنوان بخشی از یک صفحه وب نمایش می دهد. عنوان کتاب به عنوان عنوان اصلی و عنوان صفحه استفاده می شود ، عصاره به عنوان نقل قول بلوک نمایش داده می شود و پیوندی به صفحه ورود کامل ویکی پدیا در پایین تعبیه شده است.

شما همچنین با استفاده از پیش فرض صادرات قبل از اعلان ، عملکرد BookPageTemplate را به عنوان صادرات پیش فرض علامت گذاری می کنید ، زیرا Gatsby انتظار دارد که جزء React مسئول تولید صفحه رندر شده نهایی را به عنوان صادرات پیش فرض هر فایل قالب صفحه بیابد.

پس از افزودن کد قالب React به فایل ، تغییرات را ذخیره کرده و ببندید. به http: // localhost: 8000/the-c-programming-language بروید تا یک صفحه نمونه را ارائه دهید:

برای نمایش فهرستی از این گره های جدید و صفحات مرتبط با آنها ، همچنین یک صفحه فهرست اختصاصی ایجاد می کنید که همه کتابها را در یک مکان نمایش می دهد. در قسمت src/pages یک فایل جدید با نام فایل books.js ایجاد کنید. بعد ، کد زیر را به آن اضافه کنید:

src/pages/books.js

import { graphql, Link } from "gatsby";
import * as React from "react";
import Layout from "../components/layout";
import Seo from "../components/seo";

export default function BookListingsPageTemplate({ data: { allBookWikiPage } }) {
  return (
    <Layout>
      <Seo title="Programming Books Listing" />
      <p>Here are some computer programming books that have their own Wikipedia entries:</p>

      {allBookWikiPage.edges.map((edge) => {
        const node = edge.node;
        return (
          <details key={node.title}>
            <summary>{node.title}</summary>

            <div className="details-body">
              <p>{node.extract}</p>
              <div className="links">
                <Link href={node.gatsbyPath}>Internal Page</Link>
                <a rel="noreferrer" href={node.fullurl}>Wikipedia Page</a>
              </div>
            </div>
          </details>
        )
      })}
    </Layout>
  );
}

export const pageQuery = graphql`
  query {
    allBookWikiPage {
      edges {
        node {
          title
          extract
          gatsbyPath(filePath: "/{BookWikiPage.title}")
          fullurl
        }
      }
    }
  }
`;

شبیه به الگوی صفحه {BookWikiPage.title} .js ، این فایل همچنین از برچسب GraphQL pageQuery برای برداشتن داده ها از لایه GraphQL و ارسال آن به یک جزء React استفاده می کند. با این حال ، در حالی که الگوی قبلی یک کتاب را بر اساس شناسه ارائه می داد ، این الگو فهرستی از همه کتابها را ارائه می دهد ، در حالی که به صفحات کتاب جداگانه پیوند داده شده است.

هر فهرست کتاب از یک عنصر <details> استفاده می کند ، که این لیست را قادر می سازد تا قسمت کامل کتاب و پیوندها را نشان دهد یا برای نشان دادن عنوان فقط جمع شود. با پیروی از بهترین روش ها ، شما همچنین یک مقدار منحصر به فرد را به کلید در حین تکرار در آرایه منتقل می کنید ، با استفاده از مولفه Gatsby Link برای پیوندهای داخلی و یک برچسب برای پیوندهای خارجی.

رشته gatsbyPath (filePath: “/{BookWikiPage.title}”) در پرس و جو GraphQL از تابع () gatsbyPath ویژه برای بازیابی مسیر عمومی ایجاد شده بر اساس نام فایل API مسیر فایل سیستم استفاده می کند.

این فایل را ذخیره کرده و از آن خارج شوید.

با وجود تمام کتابهای موجود در یک صفحه ، حتی با بخشهای جمع شونده همه چیز کمی شلوغ شده است ، بنابراین آخرین مرحله این است که برخی از ظاهر را اضافه کنید تا خوانندگان بتوانند فهرست را آسانتر کنند. یک فایل شیوه نامه جدید در src/styles/books.css ایجاد کنید. می توانید این کار را در مرورگر فایل خود یا با خط فرمان از ریشه پروژه Gatsby انجام دهید:

mkdir -p ./src/styles
touch ./src/styles/books.css

سپس CSS زیر را به فایل اضافه کنید:

src/styles/books.css

details {
  border: 1px dotted black;
  margin: 6px;
  padding: 6px;
}

.details-body {
  background-color: #eedeff;
  margin: 4px 0px 2px 12px;
  padding: 4px;
  border-radius: 4px;
}

.links {
  display: flex;
  justify-content: space-evenly;
}

این CSS در اطراف هر فهرست کتاب ، فاصله و حاشیه های موجود در فهرست و فاصله بین پیوندهای داخلی و خارجی کتاب را اضافه می کند. پس از افزودن CSS به فایل ، قبل از ادامه آن را ذخیره و ببندید.

در نهایت ، الگوی صفحه فهرست کتاب را به روز کنید تا این فایل CSS را در آن بکشید:

src/pages/books.js

import { graphql, Link } from "gatsby";
import * as React from "react";
import Layout from "../components/layout";
import Seo from "../components/seo";
import "../styles/books.css";

این فایل را با خط وارد کردن CSS که به تازگی اضافه شده است ذخیره و ببندید.

برای مشاهده نتایج ، دوباره فرمان develop را اجرا کنید تا سرور توسعه ظاهر شود و صفحات جدید را پیش نمایش کنید:

npm run develop

اکنون می توانید به صفحه فهرست کتابهای خود در localhost دسترسی داشته باشید: 8000/books/.

شما اکنون نه تنها یک افزونه منبع Gatsby را از ابتدا ایجاد کرده اید ، بلکه از آن برای تولید صفحات بر اساس یک قالب React نیز استفاده کرده اید.

نتیجه

با دنبال کردن مراحل این آموزش ، شما اکنون ساخت افزونه منبع سفارشی را که محتوای خارجی را در پروژه Gatsby شما وارد می کند ، به پایان رسانده و از آن برای تأمین صفحات جدید در سایت خود استفاده کرده اید.

منبع افزونه ها عمق زیادی دارد. اگر علاقه مند به پیروی از بهترین شیوه ها و یادگیری مفاهیم افزونه منبع پیشرفته تر هستید ، در اینجا مواردی وجود دارد که ممکن است برای شما جالب باشد:

  • اگر می خواهید افزونه خود را با جهان به اشتراک بگذارید ، می توانید این کار را با انتشار آن در npm انجام دهید. می توانید این راهنمای انتشار بسته های npm را دنبال کنید و برای ارسال به کتابخانه افزونه Gatsby ، آن را با این گردش کار دنبال کنید.
  • برای افزونه های منبع که کارهای زیادی را با ورودی هایی انجام می دهند که برای مدت زمان یکسانی باقی می مانند ، می توانید از مزایای مکانیزم کش Gatsby بین ساخت ها استفاده کنید.
  • اگر گره های شما به یکدیگر مرتبط هستند یا به گره هایی که توسط افزونه های دیگر ایجاد شده اند ، می توانید آنها را از طریق روابط به هم پیوند دهید. این به طور خلاصه در این آموزش توضیح داده شده است ، اما می توانید جزئیات بیشتری را در اسناد Gatsby بیابید.
  • افزونه ترانسفورماتور افزونه ای است که فقط گره های یک نوع را گرفته و آنها را به گره های جدید یا اصلاح شده تبدیل می کند. در اسناد افزونه ترانسفورماتور Gatsby می توانید اطلاعات بیشتری در مورد آنها بخوانید.

c

 

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Bash’s Job Control برای مدیریت فرایندهای پیش زمینه و پس زمینه

ورود به سایت

معرفی

در آموزش قبلی ، ما در مورد نحوه استفاده از دستورات ps ، kill و nice برای کنترل فرآیندهای سیستم صحبت کردیم. این راهنما نشان می دهد که چگونه bash ، سیستم لینوکس و ترمینال شما برای ارائه فرایند و کنترل کار گرد هم می آیند.

این مقاله بر مدیریت فرایندهای پیش زمینه و پس زمینه تمرکز می کند و نشان می دهد که چگونه از عملکردهای کنترل کار پوسته خود برای افزایش انعطاف پذیری در نحوه اجرای دستورات استفاده کنید.

پیش نیازها

برای پیگیری این راهنما ، به رایانه ای نیاز دارید که رابط bash shell را اجرا می کند. bash پوسته پیش فرض در بسیاری از سیستم عامل های مبتنی بر لینوکس است و در بسیاری از سیستم عامل های مشابه یونیکس از جمله macOS موجود است. توجه داشته باشید که این آموزش با استفاده از یک سرور خصوصی مجازی لینوکس که اوبونتو 20.04 را اجرا می کند ، تأیید شده است.

اگر قصد دارید از سرور راه دور برای پیروی از این راهنما استفاده کنید ، توصیه می کنیم ابتدا راهنمای راه اندازی سرور اولیه ما را تکمیل کنید. با انجام این کار شما می توانید یک محیط سرور امن-از جمله کاربر غیر root با امتیازات sudo و فایروال پیکربندی شده با UFW-را تنظیم کنید-که می توانید از آن برای ایجاد مهارت های لینوکس خود استفاده کنید.

روش دیگر ، می توانید از ترمینال تعاملی تعبیه شده در این صفحه برای آزمایش دستورات نمونه در این آموزش استفاده کنید. روی راه اندازی یک ترمینال تعاملی زیر کلیک کنید! برای باز کردن پنجره ترمینال و شروع به کار با محیط لینوکس (اوبونتو).

مدیریت فرایندهای پیش زمینه

اکثر فرایندهایی که در دستگاه لینوکس شروع می کنید در پیش زمینه اجرا می شوند. فرمان شروع به اجرا می کند و استفاده از پوسته را در طول فرآیند مسدود می کند. این فرایند ممکن است اجازه تعامل با کاربر را بدهد یا فقط یک روش را اجرا کرده و سپس خارج شود. هر خروجی به طور پیش فرض در پنجره ترمینال نمایش داده می شود. ما در بخشهای زیر روش اصلی مدیریت فرایندهای پیش زمینه را مورد بحث قرار می دهیم.

شروع یک فرایند

به طور پیش فرض ، فرایندها در پیش زمینه شروع می شوند. این بدان معناست که تا برنامه خارج نشود یا حالت خود را تغییر ندهد ، نمی توانید با پوسته تعامل داشته باشید.

برخی از دستورات پیش زمینه خیلی سریع خارج می شوند و تقریباً بلافاصله شما را به اعلان پوسته باز می گردانند. به عنوان مثال ، دستور زیر Hello World را در ترمینال چاپ می کند و سپس شما را به خط فرمان خود باز می گرداند:

echo “Hello World”

 

Output

Hello World

اجرای سایر دستورات پیش زمینه بیشتر طول می کشد و دسترسی به پوسته را برای مدت زمان طولانی مسدود می کند. این ممکن است به این دلیل باشد که فرمان عملیات گسترده تری را انجام می دهد یا به این دلیل پیکربندی شده است که تا زمانی که صریحاً متوقف نشود اجرا شود یا تا زمانی که ورودی دیگر کاربر را دریافت نکند.

فرمانی که به طور نامحدود اجرا می شود ، ابزار برتر است. پس از شروع ، اجرا و به روز رسانی صفحه نمایش خود را ادامه می دهد تا زمانی که کاربر روند را خاتمه دهد:

top

با فشار دادن q می توانید از بالا خارج شوید ، اما برخی دیگر از فرایندها دارای عملکرد ترک اختصاصی نیستند. برای متوقف کردن آنها ، باید از روش دیگری استفاده کنید.

خاتمه یک فرایند

فرض کنید یک حلقه bash ساده را در خط فرمان راه اندازی می کنید. به عنوان مثال ، دستور زیر حلقه ای را شروع می کند که Hello World را هر ده ثانیه چاپ می کند. این حلقه برای همیشه ادامه می یابد ، تا زمانی که صریحاً خاتمه یابد:

while true; do echo “Hello World”; sleep 10; done

بر خلاف بالا ، حلقه هایی مانند این کلید “خروج” ندارند. شما باید با ارسال سیگنال ، روند را متوقف کنید. در لینوکس ، کرنل می تواند سیگنال هایی را به فرآیندهای در حال اجرا ارسال کند ، به عنوان یک درخواست برای خروج یا تغییر حالت. پایانه های لینوکس معمولاً طوری تنظیم شده اند که وقتی کاربر کلید ترکیبی CTRL + C را فشار می دهد ، سیگنال “SIGINT” (مخفف “قطع سیگنال”) را به فرایند پیش زمینه فعلی ارسال می کند. سیگنال SIGINT به برنامه می گوید که کاربر با استفاده از صفحه کلید درخواست خاتمه داده است.

برای توقف حلقه ای که شروع کرده اید ، کلید CTRL را نگه دارید و کلید C را فشار دهید:

CTRL + C

حلقه خارج می شود و کنترل را به پوسته باز می گرداند.

سیگنال SIGINT ارسال شده توسط ترکیب CTRL + C یکی از سیگنال های زیادی است که می تواند به برنامه ها ارسال شود. اکثر سیگنالها دارای ترکیب صفحه کلید مرتبط با آنها نیستند و باید با استفاده از دستور kill ارسال شوند ، که بعداً در این راهنما توضیح داده می شود.

تعلیق فرآیندها

همانطور که قبلاً ذکر شد ، فرایند پیش زمینه دسترسی به پوسته را در طول مدت اجرای آنها مسدود می کند. اگر یک فرایند را در پیش زمینه شروع کنید ، اما بعد متوجه شوید که به ترمینال نیاز دارید ، چطور؟

سیگنال دیگری که می توانید ارسال کنید ، سیگنال “SIGTSTP” است. SIGTSTP مخفف کلمه “stop terminal signal” است و معمولاً به عنوان شماره سیگنال 20 نشان داده می شود. هنگامی که CTRL + Z را فشار می دهید ، ترمینال شما فرمان “تعلیق” را ثبت می کند ، که سپس سیگنال SIGTSTP را به فرایند پیش زمینه ارسال می کند. در اصل ، این امر اجرای فرمان را متوقف کرده و کنترل را به ترمینال باز می گرداند.

برای نشان دادن تصویر ، از ping برای اتصال به google.com هر 5 ثانیه استفاده کنید. دستور زیر قبل از دستور ping فرمان دارد ، که به شما امکان می دهد از نام مستعار پوسته ای که به طور مصنوعی حداکثر تعداد فرمان را تعیین می کند ، دور بزنید:

command ping -i 5 google.com

به جای خاتمه فرمان با CTRL + C ، به جای آن CTRL + Z را فشار دهید. با این کار خروجی به این شکل برمی گردد

 

Output

[1]+  Stopped                 ping -i 5 google.com

فرمان پینگ به طور موقت متوقف شده است و به شما امکان می دهد دوباره به یک اعلان پوسته دسترسی پیدا کنید. برای نشان دادن این مورد می توانید از ابزار پردازش ps استفاده کنید:

ps T

 

Output

  PID TTY      STAT   TIME COMMAND
26904 pts/3    Ss     0:00 /bin/bash
29633 pts/3    T      0:00 ping -i 5 google.com
29643 pts/3    R+     0:00 ps t

این خروجی نشان می دهد که فرآیند پینگ هنوز فهرست شده است ، اما ستون “STAT” یک “T” در آن دارد. در صفحه ps ps ، این بدان معناست که شغلی که “با سیگنال کنترل کار متوقف شده است”.

در این راهنما نحوه تغییر حالتهای فرآیند در عمق بیشتر توضیح داده می شود ، اما در حال حاضر می توانید با تایپ کردن دستور فرمان را دوباره در پیش زمینه از سر بگیرید.

fg

پس از از سرگیری روند ، آن را با CTRL + C خاتمه دهید:

مدیریت فرایندهای پیشین

جایگزین اصلی برای اجرای یک فرایند در پیش زمینه این است که اجازه دهید در پس زمینه اجرا شود. یک فرایند پس زمینه با ترمینال خاصی که آن را شروع کرده است مرتبط است ، اما دسترسی به پوسته را مسدود نمی کند. در عوض ، در پس زمینه اجرا می شود و کاربر را قادر می سازد تا در حین اجرا فرمان با سیستم تعامل داشته باشد.

به دلیل نحوه تعامل یک فرایند پیش زمینه با ترمینال خود ، برای هر پنجره ترمینال تنها یک فرایند پیش زمینه وجود دارد. از آنجا که فرآیندهای پس زمینه کنترل را بلافاصله به پوسته باز می گردانند بدون اینکه منتظر بمانیم تا فرآیند تکمیل شود ، بسیاری از فرایندهای پس زمینه می توانند همزمان اجرا شوند.

شروع فرآیندها

می توانید با افزودن یک کاراکتر ampersand (&) به انتهای دستورات خود ، یک فرایند پس زمینه را شروع کنید. این به پوسته می گوید منتظر نمانید تا فرآیند به اتمام برسد ، بلکه باید اجرا را آغاز کرده و بلافاصله کاربر را به یک اعلان بازگرداند. خروجی فرمان همچنان در ترمینال نمایش داده می شود (مگر اینکه هدایت شود) ، اما با ادامه روند پس زمینه می توانید دستورات بیشتری را تایپ کنید.

به عنوان مثال ، می توانید همان فرایند پینگ را از قسمت قبلی در پس زمینه با تایپ کردن شروع کنید:

command ping -i 5 google.com &

سیستم کنترل کار bash خروجی را به صورت زیر برمی گرداند:

 

Output

[1] 4287

سپس خروجی معمولی را از دستور ping دریافت خواهید کرد:

 

Output

PING google.com (74.125.226.71) 56(84) bytes of data.
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=1 ttl=55 time=12.3 ms
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=2 ttl=55 time=11.1 ms
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=3 ttl=55 time=9.98 ms

با این حال ، شما همچنین می توانید دستورات را همزمان تایپ کنید. خروجی فرایند پس زمینه در بین ورودی و خروجی فرایندهای پیش زمینه شما مخلوط می شود ، اما در اجرای فرایندهای پیش زمینه تداخلی ایجاد نمی کند.

لیست فرایندهای پس زمینه

برای لیست تمام فرآیندهای متوقف شده یا پس زمینه ، می توانید از دستور jobs استفاده کنید:

jobs

اگر هنوز فرمان پینگ قبلی را در پس زمینه اجرا کرده اید ، خروجی فرمان jobs شبیه این خواهد بود:

 

Output

[1]+  Running                 command ping -i 5 google.com &

این نشان می دهد که شما در حال حاضر یک فرایند تک پس زمینه در حال اجرا دارید. [1] مشخصات کار یا شماره کار فرمان را نشان می دهد. می توانید با سایر دستورات کنترل کار و فرآیند ، مانند kill ، fg و bg ، با شماره قبلی با علامت درصد ، این مورد را ارجاع دهید. در این مورد ، شما این شغل را٪ 1 ارجاع می دهید.

توقف فرآیندهای پیش زمینه

می توانید فرایند فعلی پس زمینه را از چند طریق متوقف کنید. ساده ترین راه این است که از دستور kill با شماره کار مربوطه استفاده کنید. برای مثال ، می توانید فرایند پس زمینه در حال اجرا را با تایپ کردن از بین ببرید:

kill %1

بسته به نحوه پیکربندی پایانه شما ، بلافاصله یا دفعه بعد که ENTER را فشار می دهید ، وضعیت پایان کار در خروجی شما ظاهر می شود:

 

Output

[1]+  Terminated              command ping -i 5 google.com

اگر دوباره فرمان jobs را بررسی کنید ، هیچ کار فعلی وجود نخواهد داشت.

تغییر حالتهای فرآیند

کنون که می دانید چگونه مراحل را در پس زمینه شروع و متوقف کنید ، می توانید با تغییر وضعیت آنها آشنا شوید.

این راهنما قبلاً یکی از روشهای تغییر وضعیت یک فرآیند را توضیح داده است: توقف یا تعلیق یک فرآیند با CTRL + Z. هنگامی که فرآیندها در این حالت متوقف شده هستند ، می توانید یک فرایند پیش زمینه را به پس زمینه یا برعکس منتقل کنید.

انتقال فرآیندهای پیش زمینه به پس زمینه

اگر فراموش کنید که یک فرمان را با & هنگام شروع به کار خاتمه دهید ، همچنان می توانید روند را به پس زمینه منتقل کنید.

اولین قدم متوقف کردن مجدد فرآیند با CTRL + Z است. هنگامی که فرآیند متوقف شد ، می توانید از دستور bg برای شروع مجدد آن در پس زمینه استفاده کنید:

bg

دوباره خط وضعیت شغل را دریافت خواهید کرد ، این بار با ضمیمه اصلی اضافه شده است:

 

Output

[1]+ ping -i 5 google.com &

به طور پیش فرض ، دستور bg آخرین فرآیند متوقف شده را اجرا می کند. اگر چندین فرآیند را در یک ردیف بدون شروع مجدد متوقف کرده اید ، می توانید یک پروسه خاص را با شماره شغل آن ارجاع دهید تا روند صحیح به پس زمینه منتقل شود.

توجه داشته باشید که نمی توان همه دستورات را پس زمینه کرد. اگر برخی از فرایندها تشخیص دهند که با ورودی و خروجی استاندارد خود مستقیماً به یک ترمینال فعال متصل شده اند ، به طور خودکار خاتمه می یابد.

انتقال فرایندهای پیش زمینه به پیش زمینه

همچنین می توانید فرایندهای پس زمینه را با تایپ fg به پیش زمینه منتقل کنید:

fg

این کار بر اساس آخرین فرایند پس زمینه شما (که در خروجی فرمان jobs + نشان داده شده است) عمل می کند. بلافاصله این روند را متوقف می کند و آن را در پیش زمینه قرار می دهد. برای تعیین کار متفاوت ، از شماره شغل آن استفاده کنید:

fg %2

هنگامی که یک کار در پیش زمینه قرار دارد ، می توانید آن را با CTRL + C بکشید ، بگذارید تکمیل شود ، یا تعلیق کرده و دوباره به پس زمینه منتقل کنید

برخورد با SIGHUPs

فرایندی که در پس زمینه باشد یا در پیش زمینه ، نسبتاً محکمی با نمونه پایانی دارد که آن را آغاز کرده است. هنگامی که یک ترمینال بسته می شود ، معمولاً یک سیگنال SIGHUP به تمام فرایندهایی (پیش زمینه ، پس زمینه یا متوقف شده) که به ترمینال متصل هستند ارسال می کند. این نشان می دهد که فرآیندها خاتمه می یابد زیرا ترمینال کنترل آنها به زودی در دسترس نخواهد بود.

هر چند ممکن است مواقعی وجود داشته باشد که بخواهید یک ترمینال را ببندید اما فرایندهای پیش زمینه را در حال اجرا نگه دارید. روشهای مختلفی برای انجام این کار وجود دارد. یکی از روش های انعطاف پذیرتر استفاده از چند ضلعی ترمینال مانند صفحه نمایش یا tmux است. راه حل دیگر استفاده از ابزاری است که قابلیت جدا شدن صفحه و tmux را مانند dtach ارائه می دهد.

با این حال ، این همیشه یک گزینه نیست. گاهی اوقات این برنامه ها در دسترس نیستند یا شما قبلاً فرایندی را شروع کرده اید که باید به آن ادامه دهید. گاهی اوقات اینها ممکن است برای آنچه شما باید انجام دهید بیش از حد باشد.

استفاده از nohup

اگر هنگام شروع فرآیند می دانید که می خواهید ترمینال را قبل از اتمام فرآیند ببندید ، می توانید آن را با استفاده از دستور nohup شروع کنید. این امر باعث می شود فرآیند شروع شده در برابر سیگنال SIGHUP مصون باشد. با بسته شدن ترمینال به کار خود ادامه می دهد و مجدداً به عنوان فرزند سیستم init تعیین می شود:

nohup ping -i 5 google.com &

با این کار خطی مانند تصویر زیر برمی گردد که نشان می دهد خروجی دستور در فایلی به نام nohup.out نوشته می شود:

 

Output

nohup: ignoring input and appending output to ‘nohup.out’

این فایل در صورت قابل نوشتن در فهرست فعلی کار شما قرار می گیرد ، اما در غیر این صورت در فهرست اصلی شما قرار می گیرد. این امر برای اطمینان از از بین رفتن خروجی در صورت بسته بودن پنجره ترمینال است.

اگر پنجره ترمینال را ببندید و پنجره دیگری را باز کنید ، فرآیند همچنان اجرا می شود. شما آن را در خروجی فرمان jobs پیدا نمی کنید زیرا هر نمونه ترمینال صف شغل مستقل خود را حفظ می کند. بستن ترمینال باعث از بین رفتن کار پینگ می شود حتی اگر روند پینگ همچنان در حال اجرا باشد.

برای از بین بردن روند پینگ ، باید شناسه پردازش آن (یا “PID”) را پیدا کنید. می توانید این کار را با دستور pgrep انجام دهید (دستور pkill نیز وجود دارد ، اما این روش دو قسمتی تضمین می کند که شما فقط فرایند مورد نظر را از بین می برید). برای جستجوی اجرایی از pgrep و پرچم -a استفاده کنید:

pgrep -a ping

 

Output

7360 ping -i 5 google.com

سپس می توانید با مراجعه به PID برگشتی ، که در ستون اول است ، فرآیند را بکشید:

kill 7360

اگر دیگر نیازی به فایل nohup.out ندارید ، ممکن است بخواهید آن را حذف کنید.

استفاده از disown

دستور nohup مفید است ، اما تنها در صورتی که بدانید در زمان شروع فرآیند به آن نیاز خواهید داشت. سیستم کنترل کار bash روش های دیگری را برای دستیابی به نتایج مشابه با دستور disown داخلی ارائه می دهد.

فرمان disown در پیکربندی پیش فرض خود ، یک کار را از صف مشاغل یک ترمینال حذف می کند. این بدان معناست که دیگر نمی توان آن را با استفاده از مکانیزم های کنترل شغل که قبلاً در این راهنما توضیح داده شد مدیریت کرد ، مانند fg ، bg ، CTRL + Z ، CTRL + C. در عوض ، کار بلافاصله از لیست در خروجی مشاغل حذف می شود و هیچ دیگر با ترمینال ارتباط دارد

فرمان با تعیین یک شماره کار فراخوانی می شود. به عنوان مثال ، برای رد فوراً شغل 2 ، می توانید تایپ کنید:

disown %2

پس از بسته شدن ترمینال کنترل ، این فرایند در وضعیتی قرار می گیرد که برخلاف فرآیند nohup نیست. استثنا این است که هر خروجی در صورت بسته شدن ترمینال کنترل از بین نمی رود اگر به یک فایل هدایت نشده باشد.

معمولاً ، اگر بلافاصله پنجره ترمینال خود را نبندید ، نمی خواهید روند را به طور کامل از کنترل کار حذف کنید. می توانید به جای آن پرچم -h را به فرآیند رد کردن منتقل کنید تا روند را نادیده بگیرید و سیگنال های SIGHUP را نادیده بگیرید ، اما در غیر این صورت به عنوان یک کار معمولی ادامه دهید:

disown -h %1

در این حالت ، می توانید از مکانیزم های عادی کنترل شغل برای کنترل روند تا بستن ترمینال استفاده کنید. پس از بستن ترمینال ، اگر در هنگام راه اندازی مجدد فایل به آن هدایت نشوید ، یکبار دیگر با یک فرایند بدون خروجی گیر خواهید کرد.

برای حل این مشکل ، می توانید خروجی فرآیند خود را پس از اجرا مجدد تغییر مسیر دهید. این خارج از محدوده این راهنما است ، اما این پست توضیح می دهد که چگونه می توانید این کار را انجام دهید.

با استفاده از huponexit Shell Option

bash راه دیگری برای جلوگیری از مشکل SIGHUP برای فرآیندهای کودک دارد. گزینه پوسته huponexit کنترل می کند که آیا bash هنگام خروج سیگنال SIGHUP را به فرزند خود ارسال می کند یا خیر.

با وجود هشدارهای فوق الذکر ، مدیریت گزینه huponexit شاید یکی از ساده ترین ها برای مدیریت باشد. با تایپ کردن می توانید روشن یا خاموش بودن این ویژگی را تعیین کنید:

shopt huponexit

برای روشن کردن آن تایپ کنید:

shopt -s huponexit

اکنون ، اگر جلسه خود را با تایپ کردن exit خارج کنید ، همه فرآیندهای شما به کار خود ادامه می دهند:

exit

این گزینه در مورد خروجی برنامه به عنوان آخرین گزینه دارای هشدار است ، بنابراین مطمئن شوید که قبل از بستن ترمینال ، خروجی فرآیندهای خود را تغییر داده اید ، اگر این مهم است.

نتیجه

یادگیری کنترل شغل و نحوه مدیریت فرایندهای پیش زمینه و پس زمینه هنگام اجرای برنامه ها در خط فرمان به شما انعطاف پذیری بیشتری می بخشد. به جای باز کردن بسیاری از پنجره های ترمینال یا جلسات SSH ، اغلب می توانید با توقف زودهنگام فرآیندها یا انتقال آنها به پس زمینه در صورت لزوم ، کار کنید.

Linuxاستفاده از Bash's Job Controlخرید سرور لینوکسسرورلینوکسفروش سرورلینوکسمحیط لینوکس

  • behnam gol mohamadi
  • ۰
  • ۰

استفاده از Grep و عبارات معمولی برای جستجوی الگوهای متن در لینوکس

ورود به سایت

معرفی

دستور grep یکی از مفیدترین دستورات در محیط ترمینال لینوکس است. نام grep مخفف “global regular expression print” است. این بدان معناست که می توانید از grep برای بررسی اینکه آیا ورودی دریافت شده با الگوی مشخص شده مطابقت دارد یا خیر ، استفاده کنید. این برنامه به ظاهر بی اهمیت بسیار قدرتمند است. توانایی مرتب سازی ورودی بر اساس قوانین پیچیده ، آن را به یک پیوند محبوب در بسیاری از زنجیره های فرمان تبدیل می کند.

در این آموزش ، شما گزینه های دستور grep را بررسی می کنید و سپس برای جستجوی پیشرفته تر ، از عبارات معمولی استفاده می کنید.

پیش نیازها

برای پیگیری این راهنما ، به رایانه ای نیاز دارید که از سیستم عامل لینوکس استفاده می کند. این می تواند یک سرور خصوصی مجازی باشد که با SSH یا دستگاه محلی خود به آن متصل شده اید. توجه داشته باشید که این آموزش با استفاده از سرور لینوکس دارای Ubuntu 20.04 تأیید شده است ، اما مثالهای ذکر شده باید در رایانه ای اجرا شود که هر نسخه از توزیع لینوکس را اجرا می کند.

اگر قصد دارید از سرور راه دور برای پیروی از این راهنما استفاده کنید ، توصیه می کنیم ابتدا راهنمای راه اندازی سرور اولیه ما را تکمیل کنید. با انجام این کار شما می توانید یک محیط سرور امن-از جمله کاربر غیر root با امتیازات sudo و فایروال پیکربندی شده با UFW-را تنظیم کنید-که می توانید از آن برای ایجاد مهارت های لینوکس خود استفاده کنید.

به عنوان یک جایگزین ، ما شما را تشویق می کنیم که از ترمینال تعاملی تعبیه شده در این صفحه برای آزمایش دستورات نمونه در این آموزش استفاده کنید. روی راه اندازی یک ترمینال تعاملی زیر کلیک کنید! برای باز کردن پنجره ترمینال و شروع به کار با محیط لینوکس (اوبونتو).

کاربرد اولیه

در این آموزش ، شما از grep برای جستجوی مجوز عمومی GNU نسخه 3 برای کلمات و عبارات مختلف استفاده می کنید.

اگر از سیستم اوبونتو استفاده می کنید ، می توانید فایل را در پوشه/usr/share/common-licenses پیدا کنید. آن را در فهرست اصلی خود کپی کنید:

cp /usr/share/common-licenses/GPL-3 .

اگر از سیستم دیگری استفاده می کنید ، از دستور curl برای بارگیری نسخه استفاده کنید:

curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

همچنین در این آموزش از فایل مجوز BSD استفاده خواهید کرد. در لینوکس ، می توانید آن را با دستور زیر در فهرست اصلی خود کپی کنید:

cp /usr/share/common-licenses/BSD .

اگر از سیستم دیگری استفاده می کنید ، فایل را با دستور زیر ایجاد کنید:

cat << ‘EOF’ > BSD
Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
EOF

اکنون که فایل ها را دارید ، می توانید کار با grep را شروع کنید.

در ابتدایی ترین شکل ، از grep برای مطابقت با الگوهای تحت اللفظی درون یک فایل متنی استفاده می کنید. این بدان معناست که اگر grep یک کلمه را برای جستجو ارسال کنید ، هر خطی در فایل حاوی آن کلمه چاپ می شود.

دستور زیر را برای استفاده از grep برای جستجوی هر خطی که حاوی کلمه GNU است اجرا کنید:

grep “GNU” GPL-3

اولین استدلال ، GNU ، الگویی است که شما در جستجوی آن هستید ، در حالی که آرگومان دوم ، GPL-3 ، فایل ورودی است که می خواهید جستجو کنید.

خروجی حاصل هر خط حاوی متن الگو خواهد بود:

 

Output

                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
  Developers that use the GNU GPL protect your rights with two steps:
  "This License" refers to version 3 of the GNU General Public License.
  13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...

در برخی از سیستم ها ، الگویی که جستجو کرده اید در خروجی مشخص می شود.

گزینه های مشترک

به طور پیش فرض ، grep الگوی مشخص شده را در داخل فایل ورودی جستجو می کند و خطوط را پیدا می کند. با افزودن چند پرچم اختیاری به grep ، می توانید این رفتار را مفیدتر کنید.

اگر می خواهید grep “case” پارامتر جستجوی شما را نادیده بگیرد و تغییرات بزرگ و کوچک را جستجو کند ، می توانید گزینه -i یا-حروف کوچک را مشخص کنید.

هر نمونه از کلمه License (با حروف بزرگ ، کوچک یا مخلوط) را در همان فایل قبلی با دستور زیر جستجو کنید:

grep -i “license” GPL-3

نتایج شامل: LICENSE, license, و License:

 

Output

                    GNU GENERAL PUBLIC LICENSE
 of this license document, but changing it is not allowed.
  The GNU General Public License is a free, copyleft license for
  The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
  "This License" refers to version 3 of the GNU General Public License.
  "The Program" refers to any copyrightable work licensed under this
...
...

اگر نمونه ای در LiCeNsE وجود داشت ، آن نیز بازگردانده می شد.

اگر می خواهید تمام خطوطی که الگوی مشخصی ندارند را پیدا کنید ، می توانید از گزینه -v یا –invert -match استفاده کنید.

هر خطی را که حاوی کلمه the در مجوز BSD نیست با دستور زیر جستجو کنید:

این خروجی را دریافت خواهید کرد:

 

Output

All rights reserved.

Redistribution and use in source and binary forms, with or without
are met:
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

از آنجا که شما گزینه “نادیده گرفتن مورد” را مشخص نکرده اید ، دو مورد آخر بدون کلمه the برگشت داده شد.

اغلب دانستن شماره خطی که کبریت ها روی آن اتفاق می افتد مفید است. می توانید با استفاده از گزینه -n یا –line -number این کار را انجام دهید. مثال قبلی را با این پرچم اضافه شده دوباره اجرا کنید:

grep -vn “the” BSD

این متن زیر را برمی گرداند:

 

Output

2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13:   may be used to endorse or promote products derived from this software
14:   without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

اگر می خواهید در هر سطری که شامل خط نیست تغییراتی ایجاد کنید ، می توانید به شماره خط اشاره کنید. این امر به ویژه هنگام کار با کد منبع بسیار مفید است

عبارات با قاعده

در مقدمه ، آموختید که grep مخفف “print global express print” است. “عبارت معمولی” یک رشته متنی است که یک الگوی جستجوی خاص را توصیف می کند.

برنامه های کاربردی مختلف و زبان های برنامه نویسی عبارات معمولی را کمی متفاوت اجرا می کنند. در این آموزش شما فقط یک زیرمجموعه کوچک از نحوه توصیف الگوهای grep را بررسی خواهید کرد.

مسابقات لفظی

در مثالهای قبلی در این آموزش ، هنگامی که کلمات GNU و the را جستجو می کردید ، در واقع به دنبال عبارات معمولی معمولی بودید که با رشته دقیق کاراکترهای GNU و the مطابقت داشته باشد. الگوهایی که کاراکترهای مورد نظر را دقیقاً مشخص می کنند “تحت اللفظی” نامیده می شوند ، زیرا آنها الگو را به معنای واقعی کلمه ، شخصیت به کاراکتر مطابقت می دهند.

مفید است که اینها را به جای تطبیق یک کلمه ، با رشته ای از کاراکترها مطابقت دهید. با یادگیری الگوهای پیچیده تر ، این یک تمایز مهمتر خواهد شد.

همه کاراکترهای الفبایی و عددی (و برخی دیگر از کاراکترها) به معنای واقعی کلمه مطابقت دارند مگر اینکه توسط مکانیسم های بیان دیگر اصلاح شوند.

مسابقات لنگر

لنگرها کاراکترهای خاصی هستند که مشخص می کنند کبریت در کجا باید معتبر باشد.

به عنوان مثال ، با استفاده از لنگرها ، می توانید مشخص کنید که فقط می خواهید در مورد خطوط منطبق با GNU در ابتدای خط بدانید. برای انجام این کار ، می توانید از لنگر ^ قبل از رشته تحت اللفظی استفاده کنید.

دستور زیر را برای جستجوی فایل GPL-3 و یافتن خطوطی که GNU در ابتدای خط رخ می دهد ، اجرا کنید:

grep “^GNU” GPL-3

این دستور دو خط زیر را برمی گرداند:

 

Output

GNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published

به طور مشابه ، شما از anchor $ در انتهای الگو استفاده می کنید تا نشان دهید که تطابق فقط در صورتی معتبر خواهد بود که در انتهای یک خط رخ دهد.

این دستور با هر سطری که به کلمه ختم می شود و در فایل GPL-3 مطابقت دارد:

grep “and$” GPL-3

این خروجی را دریافت خواهید کرد:

 

Output

that there is no warranty for this free software.  For both users' and
  The precise terms and conditions for copying, distribution and
  License.  Each licensee is addressed as "you".  "Licensees" and
receive it, in any medium, provided that you conspicuously and
    alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and

مطابقت با هر کاراکتر

کاراکتر (.) در عبارات معمولی به این معنی استفاده می شود که هر کاراکتر منفرد می تواند در محل مشخص شده وجود داشته باشد.

برای مثال ، برای مطابقت هر چیزی در فایل GPL-3 که دارای دو نویسه است و سپس رشته cept ، از الگوی زیر استفاده می کنید:

grep “..cept” GPL-3

این دستور خروجی زیر را برمی گرداند:

 

Output

use, which is precisely where it is most unacceptable.  Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
  You may not propagate or modify a covered work except as expressly
  9. Acceptance Not Required for Having Copies.
...
...

این خروجی دارای موارد پذیرش و استثنا و تغییرات دو کلمه است. اگر این الگو نیز یافت می شد ، با z2cept مطابقت داشت.

عبارات براکت

با قرار دادن گروهی از کاراکترها در داخل پرانتز (\ [و \]) ، می توانید مشخص کنید که کاراکتر آن موقعیت می تواند هر یک از کاراکترهای موجود در گروه براکت باشد.

به عنوان مثال ، برای یافتن خطوطی که بیش از یک یا دو مورد را شامل می شوند ، باید با استفاده از الگوی زیر آن تغییرات را به طور مختصر مشخص کنید:

grep “t[wo]o” GPL-3

خروجی نشان می دهد که هر دو تغییر در فایل وجود دارد:

 

Output

your programs, too.
freedoms that you received.  You must make sure that they, too, receive
  Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
    Corresponding Source from a network server at no charge.
...
...

نماد براکت گزینه های جالبی را در اختیار شما قرار می دهد. با شروع لیست کاراکترهای داخل براکت ها با کاراکتر ^ ، می توانید الگو را با هر چیزی مطابقت دهید.

این مثال مانند الگوی .ode است ، اما با کد الگو مطابقت ندارد:

grep “[^c]ode” GPL-3

در اینجا خروجی دریافت خواهید کرد:

 

Output

  1. Source Code.
    model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:

توجه کنید که در خط دوم برگشتی ، در واقع ، کلمه کد وجود دارد. این نقص بیان عادی یا grep نیست. در عوض ، این خط برگشت داده شد زیرا قبلاً در خط ، حالت الگو ، که در کلمه model یافت می شد ، پیدا شد. خط برگشت داده شد زیرا نمونه ای وجود داشت که با الگو مطابقت داشت.

یکی دیگر از ویژگی های مفید براکت ها این است که می توانید طیف وسیعی از کاراکترها را به جای تایپ تک تک کاراکترهای موجود مشخص کنید.

این بدان معناست که اگر می خواهید هر سطری را که با حرف بزرگ شروع می شود پیدا کنید ، می توانید از الگوی زیر استفاده کنید:

grep “^[A-Z]” GPL-3

در اینجا خروجی این عبارت بر می گردد:

 

Output

GNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License.  Each licensee is addressed as "you".  "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
...

با توجه به برخی از مسائل مرتب سازی قدیمی ، استفاده از کلاس های کاراکتر POSIX به جای محدوده کاراکترهایی که قبلاً استفاده کرده اید ، دقیق تر است.

بحث در مورد هر کلاس نویسه POSIX خارج از محدوده این راهنما است ، اما مثالی که همان روال قبلی را انجام دهد ، از کلاس کاراکتر \ [: above: \] در انتخاب کننده براکت استفاده می کند:

grep “^[[:upper:]]” GPL-3

خروجی مانند قبل خواهد بود.

الگوی صفر یا بیشتر را تکرار کنید

سرانجام ، یکی از متا کاراکترهای متداول ، ستاره یا *است که به معنی “تکرار کاراکتر یا عبارت قبلی صفر یا بیشتر” است.

برای یافتن هر خط در فایل GPL-3 که حاوی پرانتز باز و بسته است ، فقط حروف و فاصله های بین آنها وجود دارد ، از عبارت زیر استفاده کنید:

grep “([A-Za-z ]*)” GPL-3

خروجی زیر را دریافت خواهید کرد:

 

Output

 Copyright (C) 2007 Free Software Foundation, Inc.
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
    (including a physical distribution medium), accompanied by the
    (including a physical distribution medium), accompanied by a
    place (gratis or for a charge), and offer equivalent access to the
...
...

تا کنون از علامت ها ، ستاره ها و دیگر کاراکترها در عبارات خود استفاده کرده اید ، اما گاهی اوقات باید به طور خاص آن کاراکترها را جستجو کنید.

فرار از کاراکترهای متا

مواقعی وجود دارد که باید به دنبال یک دوره واقعی یا یک بازوی اصلی باشید ، مخصوصاً هنگام کار با کد منبع یا فایلهای پیکربندی. از آنجا که این نویسه ها در عبارات معمولی معنای خاصی دارند ، باید از این کاراکترها “فرار” کنید تا به grep بگویید که نمی خواهید در این مورد از معنای خاص آنها استفاده کنید.

با استفاده از کاراکتر پشت خط (\) در مقابل کاراکتر که معمولاً معنای خاصی دارد ، از شخصیت ها فرار می کنید.

به عنوان مثال ، برای یافتن هر سطری که با حروف بزرگ شروع می شود و با یک نقطه خاتمه می یابد ، از عبارت زیر استفاده کنید که از پایان دوره فرار می کند به طوری که به جای معنای معمول “هر کاراکتر” یک دوره واقعی را نشان می دهد:

grep “^[A-Z].*\.$” GPL-3

این خروجی است که مشاهده خواهید کرد:

 

Output

Source.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.

اکنون بیایید به سایر گزینه های بیان معمولی نگاه کنیم.

توسعه عبارات منظم

دستور grep با استفاده از پرچم -E یا با فراخوانی دستور egrep به جای grep از زبان بیان منظم گسترده تری پشتیبانی می کند.

این گزینه ها قابلیت های “عبارات منظم گسترده” را باز می کند. عبارات منظم و گسترده شامل همه متا کاراکترهای اصلی و متا کاراکترهای اضافی برای بیان تطابقات پیچیده تر می شود.

گروه بندی

یکی از مفیدترین توانایی هایی که عبارات معمولی گسترده باز می کند ، توانایی گروه بندی عبارات برای دستکاری یا ارجاع به عنوان یک واحد است.

برای گروه بندی عبارات با هم ، آنها را در پرانتز بپیچید. اگر می خواهید از پرانتز بدون استفاده از عبارات معمولی گسترده استفاده کنید ، می توانید با فعال کردن این قابلیت ، آنها را با پشت سر هم فرار کنید. این بدان معناست که سه عبارت زیر از نظر عملکرد معادل هستند:

grep “\(grouping\)” file.txt
grep -E “(grouping)” file.txt
egrep “(grouping)” file.txt

جایگزینی

مشابه این که چگونه عبارات براکت می توانند گزینه های مختلف ممکن را برای مطابقت با نویسه مشخص کنند ، تناوب به شما امکان می دهد مطابقت های جایگزین برای رشته ها یا مجموعه های بیان را مشخص کنید.

برای نشان دادن تناوب ، از کاراکتر pipe | استفاده کنید. اینها اغلب در گروه بندی پرانتز استفاده می شوند تا مشخص شود که یکی از دو یا چند احتمال باید مطابقت داشته باشد.

موارد زیر یا GPL یا General Public License در متن پیدا می کند:

grep -E “(GPL|General Public License)” GPL-3

خروجی به این شکل است:

 

Output

  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
  Developers that use the GNU GPL protect your rights with two steps:
  For the developers' and authors' protection, the GPL clearly explains
authors' sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
...

Alternation می تواند بین بیش از دو گزینه با افزودن گزینه های اضافی در گروه انتخاب جدا شده با نویسه های اضافی  (|) را انتخاب کند.

کمیسازها(Quantifiers)

مانند * متا کاراکتری که با کاراکتر یا نویسه قبلی صفر یا بیشتر مطابقت داشت ، متا کاراکترهای دیگری نیز در عبارات منظم گسترده وجود دارد که تعداد وقایع را مشخص می کند.

برای مطابقت یک کاراکتر صفر یا یک بار ، می توانید از؟ شخصیت. این باعث می شود که شخصیت یا مجموعه شخصیت هایی که قبل از اختیاری آمده اند ، در اصل باشد.

موارد زیر با قرار دادن کپی در یک گروه اختیاری با حق چاپ و حق مطابقت دارد:

grep -E “(copy)?right” GPL-3

این خروجی را دریافت خواهید کرد:

 

Output

 Copyright (C) 2007 Free Software Foundation, Inc.
  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
know their rights.
  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
  "Copyright" also means copyright-like laws that apply to other kinds of
...

کاراکتر + یک یا چند بار با یک عبارت مطابقت دارد. این تقریباً شبیه کاراکتر * است ، اما با کاراکتر + ، عبارت باید حداقل یک بار مطابقت داشته باشد.

عبارت زیر با رشته رایگان به علاوه یک یا چند کاراکتر که کاراکتر فضای سفید نیستند مطابقت دارد:

grep -E “free[^[:space:]]+” GPL-3

این خروجی را مشاهده خواهید کرد:

 

Output

  The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
  When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for
you modify it: responsibilities to respect the freedom of others.
freedomss that you received.  You must make sure that they, too, receive
protecting users' freedom to change the software.  The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.

تعیین تکرار تطبیق

برای تعیین تعداد دفعات تکرار یک مسابقه ، از کاراکترهای پرانتز ({و}) استفاده کنید. این کاراکترها به شما اجازه می دهند تا تعداد دقیق ، محدوده یا محدوده بالا یا پایین را به تعداد دفعات مطابقت یک عبارت مشخص کنید.

از عبارت زیر برای پیدا کردن همه خطوط موجود در فایل GPL-3 که حاوی سه حروف صدادار هستند استفاده کنید:

grep -E “[AEIOUaeiou]{3}” GPL-3

هر سطر برگشتی دارای یک کلمه با سه مصوت است:

 

Output

changed, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this

برای مطابقت با کلماتی که بین 16 تا 20 نویسه دارند ، از عبارت زیر استفاده کنید:

grep -E “[[:alpha:]]{16,20}” GPL-3

در اینجا خروجی این فرمان است:

 

Output

    certain responsibilities if you distribute copies of the software, or if
    you modify it: responsibilities to respect the freedom of others.
        c) Prohibiting misrepresentation of the origin of that material, or

فقط خطوط حاوی کلمات در این طول نمایش داده می شود.

نتیجه

grep در یافتن الگوهای درون فایلها یا در سلسله مراتب سیستم فایل مفید است ، بنابراین ارزش وقت گذاشتن برای راحت شدن با گزینه ها و نحو آن را دارد.

عبارات معمولی حتی همه کاره تر هستند و می توانند در بسیاری از برنامه های محبوب استفاده شوند. به عنوان مثال ، بسیاری از ویرایشگران متن عبارات معمولی را برای جستجو و جایگزینی متن پیاده سازی می کنند.

علاوه بر این ، اکثر زبان های برنامه نویسی مدرن از عبارات معمولی برای انجام رویه های خاصی از داده ها استفاده می کنند. هنگامی که عبارات معمولی را درک کردید ، می توانید این دانش را به بسیاری از کارهای رایج مرتبط با رایانه ، از انجام جستجوهای پیشرفته در ویرایشگر متن تا تأیید ورودی کاربر منتقل کنید.

grepالگوهای متن در لینوکسجدیدترین سرور لینوکسخریدسرورلینوکسسرورلینوکسلینوکس

  • behnam gol mohamadi
  • ۰
  • ۰

چگونه می توان نتایج پرس و جو را در Laravel Eloquent محدود و پیج بندی کرد

ورود به سایت

در طول این مجموعه ، شما پیوندهای جدیدی را به برنامه نمایشی خود اضافه کرده اید تا چندین ویژگی از Laravel Eloquent را آزمایش کنید. شاید متوجه شده باشید که صفحه فهرست اصلی هربار که پیوند جدیدی اضافه می کنید طولانی تر می شود ، زیرا محدودیتی در تعداد پیوندهای نشان داده شده در برنامه وجود ندارد. اگرچه وقتی تعداد اندکی از ورودی های پایگاه داده را دارید ، مشکلی ایجاد نمی شود ، اما در طولانی مدت ممکن است زمان بارگذاری صفحه شما طولانی تر شود ، و چیدمانی که بخاطر میزان انتشار محتوا در آن خواندن مشکل تر است. یک صفحه واحد

در این قسمت از سری ، نحوه محدود کردن تعداد نتایج در پرس و جو Laravel Eloquent با روش limit () و نحوه صفحه بندی نتایج با روش simplePaginate () را خواهید آموخت.

محدود کردن نتایج پرس و جو

برای شروع ، مسیر اصلی برنامه (/) خود را به روز می کنید تا تعداد پیوندهایی که در صفحه فهرست شما فهرست شده اند محدود شود.

با باز کردن فایل مسیرهای وب خود در ویرایشگر کد شروع کنید:

routes/web.php

سپس ، تعریف مسیر اصلی را پیدا کنید:

routes/web.php

Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

خط برجسته پرس و جو را نشان می دهد که تمام پیوندهای موجود در پایگاه داده را از طریق متد Link model all () دریافت می کند. همانطور که در قسمت قبلی این سری توضیح داده شد ، این روش از کلاس Model وراثت می شود و مجموعه ای را با تمام رکوردهای پایگاه داده مرتبط با آن مدل باز می گرداند. روش sortDesc () برای مرتب سازی مجموعه حاصله به ترتیب نزولی استفاده می شود.

اکنون خط برجسته را برای استفاده از روش مرتب سازی پرس و جو پایگاه داده orderBy () تغییر می دهید ، که نتایج پرس و جو را در سطح پایگاه داده سفارش می دهد ، به جای این که مجموعه کامل ردیف هایی را که به عنوان مجموعه فصیح از طریق روش (() بازگردانده می شوند ، به سادگی مرتب کنید. به همچنین برای محدود کردن نتایج پرس و جو ، یک روش زنجیره ای به روش limit () اضافه می کنید. در نهایت ، از روش get () برای بدست آوردن مجموعه نتایج فیلتر شده به عنوان مجموعه ای فصیح استفاده خواهید کرد.

مسیر اصلی خود را با کد زیر جایگزین کنید. این تغییر برای راحتی شما برجسته شده است:

routes/web.php

Route::get('/', function () {
    $links = Link::orderBy('created_at', 'desc')->limit(4)->get();

    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

کد به روز شده اکنون آخرین 4 پیوند اضافه شده به پایگاه داده را بدون توجه به اینکه در کدام لیست قرار دارد ، می کشد. از آنجا که همه پیوندها به لیست ها اضافه می شوند ، بازدیدکنندگان همچنان می توانند برای مشاهده لیست کامل پیوندها به لیست های خاصی مراجعه کنند.

در مرحله بعد ، نحوه صفحات بندی نتایج را یاد می گیرید تا مطمئن شوید همه پیوندها همچنان در دسترس هستند ، حتی اگر همه آنها به یکباره در یک صفحه بارگیری نشوند.

نتایج جستجوی پیجینی

صفحه فهرست شما اکنون تعداد پیوندهای فهرست شده را محدود می کند ، به طوری که صفحه شما با محتوا بیش از حد بارگیری نمی شود و در مدت زمان کوتاه تر ارائه می شود. در حالی که این راه حل در بسیاری از موارد خوب عمل می کند ، باید مطمئن شوید که بازدیدکنندگان هنوز می توانند به پیوندهای قدیمی که به طور پیش فرض قابل مشاهده نیستند دسترسی داشته باشند. مؤثرترین روش برای انجام این کار پیاده سازی صفحه بندی است که در آن کاربران می توانند بین چندین صفحه نتایج حرکت کنند.

Laravel Eloquent روشهای بومی برای تسهیل پیاده سازی صفحه نتایج جستار پایگاه داده دارد. روشهای paginate () و simplePaginate () به ایجاد پیوندهای صفحه بندی ، رسیدگی به پارامترهای HTTP برای شناسایی صفحه ای که در حال حاضر درخواست می شود ، و جستجوی پایگاه داده با محدودیت و جابجایی صحیح به منظور دستیابی به مجموعه مورد انتظار نتایج ، بستگی دارد. تعداد سوابق در هر صفحه ای که می خواهید لیست کنید.

اکنون می توانید پرس و جوهای Eloquent را در route/web.php به روز کنید تا از متد simplePaginate () استفاده کنید ، که با پیوندهای قبلی و بعدی یک ناوبری اساسی ایجاد می کند. بر خلاف روش paginate () ، simplePaginate () اطلاعاتی درمورد تعداد کل صفحات در نتیجه پرس و جو نشان نمی دهد.

فایل route/web.php را در ویرایشگر کد خود باز کنید. با به روز رسانی / route ، جایگزین محدودیت (4)-> فراخوانی متد get () با متد () simplePaginate:

routes/web.php

...
Route::get('/', function () {
    $links = Link::orderBy('created_at', 'desc')->simplePaginate(4);

    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});
...

 

در مرحله بعد ، تعریف مسیر /{slug} را در همان فایل قرار دهید و متد get () را با روش simplePaginate () جایگزین کنید. پس از اتمام کار کد باید به این شکل باشد:

routes/web.php

...
Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links()->orderBy('created_at', 'desc')->simplePaginate(4),
        'lists' => LinkList::all()
    ]);
})->name('link-list');
...

پس از اتمام کار ، مسیرهای نهایی/فایل web.php به این شکل ظاهر می شود. تغییرات برای راحتی شما برجسته شده است:

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $links = Link::orderBy('created_at', 'desc')->simplePaginate(4);

    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links()->orderBy('created_at', 'desc')->simplePaginate(4),
        'lists' => LinkList::all()
    ]);
})->name('link-list');

پس از اتمام فایل را ذخیره کنید.

درخواست های پایگاه داده در حال حاضر به روز شده اند ، اما شما هنوز هم باید نمای جلویی خود را به روز کنید تا کدی را که نوار ناوبری را نشان می دهد ، شامل شود. مجموعه Eloquent به دست آمده با () simplePaginate شامل روشی به نام () است که می تواند از نمای جلویی فراخوانی شود تا کد HTML لازم را برای خروجی بخش ناوبری بر اساس یک پرس و جوی صفحه بندی شده ارائه دهد.

همچنین می توانید از روش پیوندها () در یک مجموعه صفحه بندی شده Eloquent برای دسترسی به شی صفحه بندی کننده ذاتی استفاده کنید ، که چندین روش مفید را برای به دست آوردن اطلاعات در مورد محتوا مانند صفحه فعلی و اینکه صفحات متعدد محتوا وجود دارد یا خیر ، ارائه می دهد.

نمای برنامه منابع/views/index.blade.php را در ویرایشگر کد خود باز کنید:

resources/views/index.blade.php

انتهای بخش دارای برچسب کلاس پیوندها را مشخص کنید ، که شامل حلقه foreach است که پیوندها در آن رندر می شوند. کد زیر را بعد از آن بخش و قبل از برچسب </div> آخر در آن صفحه قرار دهید:

resources/views/index.blade.php

@if ($links->links()->paginator->hasPages())
    <div class="mt-4 p-4 box has-text-centered">
        {{ $links->links() }}
    </div>
@endif

ین کد با دسترسی به شی paginator و فراخوانی متد hasPages () ، وجود چندین صفحه از نتایج را بررسی می کند. وقتی این متد true می شود ، صفحه یک عنصر div جدید ارائه می دهد و متد links () را برای چاپ پیوندهای ناوبری برای پرس و جو مربوط به Eloquent فراخوانی می کند.

پس از اتمام کار ، صفحه به روز شده index.blade.php به این شکل خواهد بود:

resources/views/index.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My Awesome Links</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">

    <style>
        html {
            background: url("https://i.imgur.com/BWIdYTM.jpeg") no-repeat center center fixed;
            -webkit-background-size: cover;
            -moz-background-size: cover;
            -o-background-size: cover;
            background-size: cover;
        }

        div.link h3 {
            font-size: large;
        }

        div.link p {
            font-size: small;
            color: #718096;
        }
    </style>
</head>
<body>
<section class="section">
    <div class="container">
        <h1 class="title">
            @if (isset($list))
                {{ $list->title }}
            @else
                Check out my awesome links
            @endif
        </h1>
        <p class="subtitle">
            @foreach ($lists as $list)<a href="{{ route('link-list', $list->slug) }}" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }} ({{ $list->links()->count() }})</a> @endforeach
        </p>

        <section class="links">
            @foreach ($links as $link)
                <div class="box link">
                    <h3><a href="{{ $link->url }}" target="_blank" title="Visit Link: {{ $link->url }}">{{ $link->description }}</a></h3>
                    <p>{{$link->url}}</p>
                    <p class="mt-2"><a href="{{ route('link-list', $link->link_list->slug) }}" title="{{ $link->link_list->title }}" class="tag is-info">{{ $link->link_list->title }}</a></p>
                </div>
            @endforeach
        </section>

        @if ($links->links()->paginator->hasPages())
            <div class="mt-4 p-4 box has-text-centered">
                {{ $links->links() }}
            </div>
        @endif
    </div>
</section>
</body>
</html>

پس از اتمام به روزرسانی فایل را ذخیره کنید. اگر به پنجره مرورگر خود برگردید و صفحه برنامه را دوباره بارگیری کنید ، هرگاه بیش از 4 پیوند در فهرست کلی یا در هر صفحه فهرست پیوندهای جداگانه داشته باشید ، به یک نوار ناوبری جدید توجه خواهید کرد.

با یک صفحه بندی کاربردی در محل ، می توانید محتوای خود را افزایش دهید در حالی که مطمئن می شوید که اقلام قدیمی هنوز در دسترس کاربران و موتورهای جستجو هستند. در مواردی که شما فقط به مقدار مشخصی از نتایج بر اساس معیارهای خاصی نیاز دارید ، درصورتی که صفحه بندی لازم نیست ، می توانید از روش limit () برای ساده سازی پرس و جو و تضمین مجموعه محدود نتایج استفاده کنید.

Laravel EloquentSQLsqlserverپایگاه دادهخرید سرورفروش سرورنتایج پرس و جو

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از دکوراتورها در TypeScript

ورود به سایت

معرفی

TypeScript افزونه ای از زبان جاوا اسکریپت است که از زمان اجرای جاوا اسکریپت با یک نوع تایپ کننده زمان کامپایل استفاده می کند. این ترکیب به توسعه دهندگان اجازه می دهد تا از اکوسیستم جاوا اسکریپت و ویژگی های زبان کامل استفاده کنند ، در حالی که علاوه بر این ، نوع تایپ استاتیک ، شمارش ها ، کلاس ها و رابط ها را در بالای آن اضافه می کنند. یکی از این ویژگی های اضافی پشتیبانی از دکوراتور است.

دکوراتورها راهی برای decorator اعضای یک کلاس یا خود کلاس با قابلیت های اضافی هستند. هنگامی که از یک decorator کننده برای یک کلاس یا عضو کلاس استفاده می کنید ، در واقع یک تابع را فراخوانی می کنید که جزئیات decorator شده را دریافت می کند ، و اجرای decorator قادر خواهد بود کد را به صورت پویا تغییر داده و قابلیت های اضافی را اضافه کند. کاهش کد بویلر آنها راهی برای متا برنامه نویسی در TypeScript هستند ، که یک تکنیک برنامه نویسی است که برنامه نویس را قادر می سازد تا کدی ایجاد کند که از کدهای دیگر خود برنامه به عنوان داده استفاده کند.

این آموزش به شما نشان می دهد که چگونه decorator خود را در TypeScript برای کلاس ها و اعضای کلاس ایجاد کنید ، و همچنین نحوه استفاده از آنها. شما را از طریق نمونه کد های مختلف راهنمایی می کند ، که می توانید آنها را در محیط TypeScript خود یا TypeScript Playground دنبال کنید ، یک محیط آنلاین که به شما امکان می دهد TypeScript را مستقیماً در مرورگر بنویسید.

پیش نیازها

برای پیگیری این آموزش ، شما نیاز دارید:

  • محیطی که در آن می توانید برنامه های TypeScript را اجرا کنید تا همراه با مثال ها دنبال کنید. برای تنظیم این دستگاه در دستگاه محلی خود ، به موارد زیر نیاز دارید.
    • هر دو Node و npm (یا نخ) به منظور اجرای یک محیط توسعه که بسته های مربوط به TypeScript را مدیریت می کند ، نصب شده است. این آموزش با Node.js نسخه 14.3.0 و npm نسخه 6.14.5 آزمایش شده است. برای نصب روی macOS یا اوبونتو 18.04 ، مراحل نحوه نصب Node.js و ایجاد محیط توسعه محلی در macOS یا بخش Installing using a PPA از نحوه نصب Node.js در اوبونتو 18.04 را دنبال کنید. اگر از زیر سیستم Windows برای Linux (WSL) استفاده می کنید ، این نیز کار می کند.
    • علاوه بر این ، به TypeScript Compiler (tsc) نصب شده بر روی دستگاه خود نیاز دارید. برای انجام این کار ، به وب سایت رسمی TypeScript مراجعه کنید.
  • اگر نمی خواهید محیط TypeScript را در دستگاه محلی خود ایجاد کنید ، می توانید از زمین بازی رسمی TypeScript برای پیگیری استفاده کنید.
  • شما به دانش کافی در مورد جاوا اسکریپت ، به ویژه نحو ES6+ ، مانند تخریب ، عملگرهای استراحت و واردات/صادرات نیاز دارید. اگر به اطلاعات بیشتری در مورد این موضوعات نیاز دارید ، خواندن نحوه کدگذاری در سری JavaScript توصیه می شود
  • این آموزش به جنبه های ویرایشگرهای متنی که از TypeScript پشتیبانی می کنند اشاره می کند و خطاهای خطی را نشان می دهد. این برای استفاده از TypeScript ضروری نیست ، اما از ویژگیهای TypeScript بیشتر استفاده می کند. برای به دست آوردن مزایای این موارد ، می توانید از ویرایشگر متنی مانند Visual Studio Code استفاده کنید که از TypeScript پشتیبانی کامل دارد. همچنین می توانید این مزایا را در TypeScript Playground امتحان کنید

همه نمونه های نشان داده شده در این آموزش با استفاده از TypeScript نسخه 4.2.2 ایجاد شده است.

فعال کردن پشتیبانی Decorators در TypeScript

در حال حاضر ، decorator هنوز یک ویژگی آزمایشی در TypeScript هستند و بنابراین ، ابتدا باید آن را فعال کنید. در این بخش ، بسته به نحوه کار با TypeScript ، نحوه فعال کردن decorator در TypeScript را خواهید دید.

CLI کامپایلر TypeScript

برای فعال کردن پشتیبانی دکوراتورها در هنگام استفاده از TypeScript Compiler CLI (tsc) تنها مرحله اضافی مورد نیاز این است که یک پرچم اضافی –experimentalDecorators:

tsc –experimentalDecorators

tsconfig.json

هنگام کار در پروژه ای که دارای فایل tsconfig.json است ، برای فعال کردن decorator تجربی ، باید ویژگی experimentalDecorators را به شیء compilerOptions اضافه کنید:

{
“compilerOptions”: {
“experimentalDecorators”: true
}
}

در زمین بازی TypeScript ، دکوراتورها به طور پیش فرض فعال هستند.

با استفاده از نحو دکوراتور

در این بخش ، شما در کلاسهای TypeScript از decorator استفاده خواهید کرد.

در TypeScript ، می توانید با استفاده از نحو خاصexpression ، decorator کننده ایجاد کنید ، جایی که بیان یک تابع است که به طور خودکار در زمان اجرا با جزئیات مربوط به هدفdecorator فراخوانی می شود.

هدف یک دکوراتور بستگی به جایی دارد که آنها را اضافه می کنید. در حال حاضر ، decorator را می توان به اجزای زیر کلاس اضافه کرد:

  • خود اعلام کلاس
  • خواص
  • دستیاران
  • مواد و روش ها
  • مولفه های

برای مثال ، فرض کنید شما یک decorator به نام مهر و موم شده دارید که Object.seal را در یک کلاس فراخوانی می کند. برای استفاده از دکوراتور خود می توانید موارد زیر را بنویسید:

@sealed
class Person {}

در کد برجسته شده توجه کنید که decorator را درست قبل از هدف decorator مهر و موم شده خود اضافه کرده اید ، در این مورد ، اعلان کلاس Person.

همین امر برای انواع دیگر decorators معتبر است:

@classDecorator
class Person {
  @propertyDecorator
  public name: string;

  @accessorDecorator
  get fullName() {
    // ...
  }

  @methodDecorator
  printName(@parameterDecorator prefix: string) {
    // ...
  }
}

 

برای افزودن چند decorator ، آنها را یکی پس از دیگری به هم اضافه کنید:

@decoratorA
@decoratorB
class Person {}

ایجاد دکوراتورهای کلاس در TypeScript

در این بخش مراحل ایجاد decorator کلاس در TypeScript را طی خواهید کرد.

برای decorator به نامdecoratorA ، به TypeScript می گویید که باید تابع decoratorA را فراخوانی کند. یک تابع با جزئیات نحوه استفاده از decorator در کد خود فراخوانی می شود. به عنوان مثال ، اگر decorator را برای اعلان کلاس اعمال کرده اید ، تابع جزئیات مربوط به کلاس را دریافت می کند. این عملکرد باید در حدی باشد که دکوراتور شما بتواند کار کند.

برای ایجاد دکوراتور خود ، باید تابعی با همان نام decorator خود ایجاد کنید. به این معنی که برای ایجاد decorator کلاس مهر و موم شده که در قسمت قبل مشاهده کردید ، باید یک تابع مهر و موم شده ایجاد کنید که مجموعه خاصی از پارامترها را دریافت می کند. بیایید دقیقاً همین کار را انجام دهیم:

@sealed
class Person {}

function sealed(target: Function) {
  Object.seal(target);
  Object.seal(target.prototype);
}

پارامتر (های) منتقل شده به دکوراتور بستگی به محل استفاده از دکوراتور دارد. پارامتر اول معمولاً هدف نامیده می شود.

دکوراتور مهر و موم شده فقط در اعلان های کلاس استفاده می شود ، بنابراین عملکرد شما یک پارامتر واحد ، هدف ، که از نوع Function است دریافت می کند. این سازنده کلاسی خواهد بود که decorator کننده روی آن اعمال شده است.

در تابع مهر و موم شده ، سپس Object.seal را روی هدف ، که سازنده کلاس است ، و همچنین در نمونه اولیه آنها فراخوانی می کنید. هنگامی که این کار را انجام می دهید ، هیچ ویژگی جدیدی نمی تواند به سازنده کلاس یا ویژگی آنها اضافه شود ، و خصوصیات موجود به عنوان غیر قابل تنظیم علامت گذاری می شوند.

مهم است که به یاد داشته باشید که در حال حاضر نمی توان نوع TypeScript هدف را هنگام استفاده از decorator گسترش داد. این بدان معناست که ، به عنوان مثال ، شما نمی توانید یک فیلد جدید با استفاده از یک تزئین کننده به کلاس اضافه کنید و آن را از نظر نوع ایمن کنید.

اگر درdecorator کلاس مهر و موم شده مقداری را برگردانید ، این مقدار به تابع سازنده جدید کلاس تبدیل می شود. این می تواند مفید باشد اگر می خواهید سازنده کلاس را به طور کامل بازنویسی کنید.

شما اولین decorator کننده خود را ایجاد کرده اید و از آن در کلاس استفاده کرده اید. در قسمت بعدی نحوه ایجاد کارخانه های decorator را خواهید آموخت.

ایجاد Decorator Factories

گاهی اوقات هنگام استفاده از دکوراتور باید گزینه های اضافی را به دکوراتور منتقل کنید و برای این کار باید از کارخانه های decorator استفاده کنید. در این بخش نحوه ایجاد آن کارخانه ها و استفاده از آنها را خواهید آموخت.

کارخانه های decorator توابعی هستند که عملکرد دیگری را برمی گردانند. آنها این نام را دریافت می کنند زیرا خود اجرای decorator نیستند. در عوض ، آنها عملکرد دیگری را که مسئول اجرای decorator است ، باز می گردانند و به عنوان یک تابع بسته بندی عمل می کنند. آنها در سفارشی سازی دکوراتورها مفید هستند ، زیرا اجازه می دهند کد مشتری هنگام استفاده از گزینه ها به decorator منتقل کند.

بیایید تصور کنیم که شما یک دکوراتور کلاس به نام decoratorA دارید و می خواهید گزینه ای را اضافه کنید که می توانید هنگام فراخوانی با دکوراتور مانند پرچم بولی تنظیم کنید. شما می توانید با نوشتن یک کارخانه تزئیناتی مشابه کارخانه زیر به این مهم برسید:

const decoratorA = (someBooleanFlag: boolean) => {
  return (target: Function) => {
  }
}

در اینجا ، تابع decoratorA با پیاده سازی تزئین کننده ، عملکرد دیگری را برمی گرداند. توجه کنید که چگونه کارخانه تزئینات پرچم بولی را به عنوان تنها پارامتر خود دریافت می کند:

const decoratorA = (someBooleanFlag: boolean) => {
  return (target: Function) => {
  }
}

هنگام استفاده از دکوراتور ، می توانید مقدار این پارامتر را منتقل کنید. کد برجسته شده را در مثال زیر مشاهده کنید:

const decoratorA = (someBooleanFlag: boolean) => {
  return (target: Function) => {
  }
}

@decoratorA(true)
class Person {}

در اینجا ، وقتی از decoratorA decorator استفاده می کنید ، قرار است کارخانه تزئینات با پارامتر someBooleanFlag روی true تنظیم شود. سپس اجرای تزئین کننده خود اجرا می شود. این به شما امکان می دهد رفتار دکوراتور خود را بر اساس نحوه استفاده از آن تغییر دهید ، و سفارشی سازی و استفاده مجدد از دکوراتورها را از طریق برنامه خود آسان کنید.

توجه داشته باشید که لازم است تمام پارامترهای مورد انتظار کارخانه دکوراتور را گذرانده باشید. اگر به سادگی از دکوراتور بدون عبور از پارامترها استفاده کرده اید ، مانند مثال زیر:

const decoratorA = (someBooleanFlag: boolean) => {
  return (target: Function) => {
  }
}

@decoratorA
class Person {}

کامپایلر TypeScript دو خطا به شما می دهد که ممکن است بسته به نوع تزئین کننده متفاوت باشد. برای تزئین کنندگان کلاس خطاها 1238 و 1240 است:

 

Output

Unable to resolve signature of class decorator when called as an expression.
  Type '(target: Function) => void' is not assignable to type 'typeof Person'.
    Type '(target: Function) => void' provides no match for the signature 'new (): Person'. (1238)
Argument of type 'typeof Person' is not assignable to parameter of type 'boolean'. (2345)

شما فقط یک کارخانه تزئینات ایجاد کرده اید که قادر به دریافت پارامترها و تغییر رفتار آنها بر اساس این پارامترها است. در مرحله بعد با نحوه ایجاد تزئین کننده املاک آشنا می شوید.

ایجاد Property Decorators

ویژگی های کلاس مکان دیگری است که می توانید از دکوراتور استفاده کنید. در این بخش نحوه ایجاد آنها را بررسی می کنید.

هر دکوراتور املاک پارامترهای زیر را دریافت می کند:

  • برای خواص استاتیک ، تابع سازنده کلاس. برای سایر ویژگی ها ، نمونه اولیه کلاس.
  • نام عضو.

در حال حاضر ، هیچ راهی برای به دست آوردن توصیف ویژگی به عنوان پارامتر وجود ندارد. این به دلیل روشی است که طراحان ویژگی در TypeScript راه اندازی می شوند.

در اینجا یک عملکرد تزئین کننده وجود دارد که نام اعضا را روی کنسول چاپ می کند:

const printMemberName = (target: any, memberName: string) => {
console.log(memberName);
};

class Person {
@printMemberName
name: string = “Jon”;
}

وقتی کد TypeScript بالا را اجرا می کنید ، موارد زیر را در کنسول چاپ می کنید:

 

Output

name

می توانید از طراحان املاک برای نادیده گرفتن ملک مورد تزئین استفاده کنید. این را می توان با استفاده از Object.defineProperty همراه با یک setter و getter جدید برای ویژگی انجام داد. بیایید ببینیم چگونه می توانید یک تزئین کننده با نام فهرست مجاز ایجاد کنید ، که فقط اجازه می دهد یک ویژگی بر روی مقادیر موجود در یک لیست مجاز استاتیک تنظیم شود:

const allowlist = ["Jon", "Jane"];

const allowlistOnly = (target: any, memberName: string) => {
  let currentValue: any = target[memberName];

  Object.defineProperty(target, memberName, {
    set: (newValue: any) => {
      if (!allowlist.includes(newValue)) {
        return;
      }
      currentValue = newValue;
    },
    get: () => currentValue
  });
};

ابتدا ، شما یک لیست مجاز استاتیک در بالای کد ایجاد می کنید:

const allowlist = [“Jon”, “Jane”];

سپس در حال پیاده سازی تزئین کننده اموال هستید:

const allowlistOnly = (target: any, memberName: string) => {
  let currentValue: any = target[memberName];

  Object.defineProperty(target, memberName, {
    set: (newValue: any) => {
      if (!allowlist.includes(newValue)) {
        return;
      }
      currentValue = newValue;
    },
    get: () => currentValue
  });
};

توجه داشته باشید که چگونه از هر کدام به عنوان نوع هدف استفاده می کنید:

const allowlistOnly = (target: any, memberName: string) => {

برای طراحان ویژگی ، نوع پارامتر هدف می تواند سازنده کلاس یا نمونه اولیه کلاس باشد ، در این شرایط استفاده از آن آسان تر است.

در خط اول پیاده سازی تزئین کننده خود ، مقدار فعلی دارایی را که تزئین می کنید در متغیر currentValue ذخیره می کنید:

let currentValue: any = target[memberName];

برای خواص استاتیک ، در صورت وجود ، مقدار پیش فرض آنها تنظیم می شود. برای خواص غیر استاتیک ، این همیشه تعریف نشده است. این به این دلیل است که در زمان اجرا ، در کد جاوا اسکریپت کامپایل شده ، تزئین کننده قبل از اینکه ویژگی نمونه روی مقدار پیش فرض تنظیم شود ، اجرا می شود.

سپس با استفاده از Object.defineProperty ویژگی را لغو می کنید:

Object.defineProperty(target, memberName, {
  set: (newValue: any) => {
    if (!allowlist.includes(newValue)) {
      return;
    }
    currentValue = newValue;
  },
  get: () => currentValue
});

فراخوانی Object.defineProperty دارای getter و setter است. دریافت کننده مقدار ذخیره شده در متغیر currentValue را برمی گرداند. اگر تنظیم کننده مقدار currentVariable را روی newValue تنظیم کند ، اگر در لیست مجاز باشد.

بیایید از دکوراتوری که شما نوشتید استفاده کنیم. کلاس Person زیر را ایجاد کنید:

class Person {
  @allowlistOnly
  name: string = "Jon";
}

اکنون یک نمونه جدید از کلاس خود ایجاد می کنید ، و تنظیمات آزمایشی و بدست آوردن ویژگی نمونه نام:

const allowlist = ["Jon", "Jane"];

const allowlistOnly = (target: any, memberName: string) => {
  let currentValue: any = target[memberName];

  Object.defineProperty(target, memberName, {
    set: (newValue: any) => {
      if (!allowlist.includes(newValue)) {
        return;
      }
      currentValue = newValue;
    },
    get: () => currentValue
  });
};

class Person {
  @allowlistOnly
  name: string = "Jon";
}

const person = new Person();
console.log(person.name);

person.name = "Peter";
console.log(person.name);

person.name = "Jane";
console.log(person.name);

 

هنگام اجرای کد باید خروجی زیر را مشاهده کنید:

 

Output

Jon
Jon
Jane

مقدار هرگز روی Peter تنظیم نمی شود ، زیرا Peter در لیست مجاز نیست.

اگر می خواهید کد خود را کمی بیشتر استفاده کنید و اجازه دهید هنگام استفاده از دکوراتور ، لیست مجاز تنظیم شود ، چه می کنید؟ این یک مورد استفاده عالی برای decorator factories. است. بیایید دقیقاً همین کار را انجام دهیم ، با تبدیل دکوراسیون مجاز خود فقط دکوراتور به decorator factories.:

const allowlistOnly = (allowlist: string[]) => {
  return (target: any, memberName: string) => {
    let currentValue: any = target[memberName];

    Object.defineProperty(target, memberName, {
      set: (newValue: any) => {
        if (!allowlist.includes(newValue)) {
          return;
        }
        currentValue = newValue;
      },
      get: () => currentValue
    });
  };
}

در اینجا شما پیاده سازی قبلی خود را به یک عملکرد دیگر ، یک کارخانه تزئینات ، پیچانده اید. کارخانه تزئینات یک پارامتر به نام مجاز لیست دریافت می کند که مجموعه ای از رشته ها است.

اکنون برای استفاده از دکوراتور خود ، باید از فهرست مجاز مانند کد برجسته زیر عبور کنید:

class Person {
  @allowlistOnly(["Claire", "Oliver"])
  name: string = "Claire";
}

سعی کنید کدی شبیه کد قبلی که نوشتید اجرا کنید ، اما با تغییرات جدید:

const allowlistOnly = (allowlist: string[]) => {
  return (target: any, memberName: string) => {
    let currentValue: any = target[memberName];

    Object.defineProperty(target, memberName, {
      set: (newValue: any) => {
        if (!allowlist.includes(newValue)) {
          return;
        }
        currentValue = newValue;
      },
      get: () => currentValue
    });
  };
}

class Person {
  @allowlistOnly(["Claire", "Oliver"])
  name: string = "Claire";
}

const person = new Person();
console.log(person.name);
person.name = "Peter";
console.log(person.name);
person.name = "Oliver";
console.log(person.name);

کد باید خروجی زیر را به شما بدهد:

 

Output

Claire
Claire
Oliver

نشان می دهد که آنطور که انتظار می رود کار می کند ، person.name هرگز روی Peter تنظیم نمی شود ، زیرا Peter در فهرست مجاز داده شده نیست.

اکنون که اولین تزئین کننده دارایی خود را با استفاده از عملکرد معمول تزئین کننده و کارخانه تزئینات ایجاد کرده اید ، وقت آن است که به نحوه ایجاد تزئینات برای دستیاران کلاس نگاهی بیندازید.

ایجاد Accessor Decorators

در این قسمت نگاهی به چگونگی تزئین اعضای کلاس می اندازید.

درست مانند دکوراتورهای املاک ، دکوراتورهای مورد استفاده در یک accessor پارامترهای زیر را دریافت می کنند:

برای خواص استاتیک ، تابع سازنده کلاس ، برای همه خواص دیگر ، نمونه اولیه کلاس.
نام عضو.
اما متفاوت از دکوراتور ویژگی ، پارامتر سوم را نیز با ویژگی توصیف کننده ویژگی عضو دسترسی دریافت می کند.

با توجه به این واقعیت که ویژگی های توصیف کننده شامل هر دو تنظیم کننده و گیرنده برای یک عضو خاص است ، تزئین کننده های جانبی فقط می توانند برای تنظیم کننده یا گیرنده یک عضو واحد اعمال شوند ، نه برای هر دو.

اگر یک مقدار از تزئین کننده accessor خود را برگردانید ، این مقدار به عنوان توصیف کننده ویژگی جدید accessor برای هر دو گروه getter و setter تبدیل می شود.

در اینجا نمونه ای از یک تزئین کننده است که می تواند برای تغییر پرچم قابل شمارش دسترسی گیرنده/تنظیم کننده استفاده شود:

const enumerable = (value: boolean) => {
  return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
    propertyDescriptor.enumerable = value;
  }
}

در مثال به نحوه استفاده از کارخانه تزئینات توجه کنید. این به شما این امکان را می دهد که هنگام تماس با دکوراتور پرچم شمارش شده را مشخص کنید. در اینجا نحوه استفاده از دکوراتور خود آورده شده است:

class Person {
  firstName: string = "Jon"
  lastName: string = "Doe"

  @enumerable(true)
  get fullName () {
    return `${this.firstName} ${this.lastName}`;
  }
}

دکوراتورهای اکسسوری شبیه به دکوراتورهای املاک هستند. تنها تفاوت این است که آنها پارامتر سوم را با توصیف کننده ویژگی دریافت می کنند. اکنون که اولین تزئین کننده اکسسوری خود را ایجاد کرده اید ، بخش بعدی نحوه ایجاد تزئین کننده متد را به شما نشان می دهد.

ایجاد Method Decorators

در این قسمت نگاهی به نحوه استفاده از تزئین کننده های متد می اندازید.

اجرای روش های تزئینات بسیار شبیه به نحوه ایجاد تزئینات اکسسوری است. پارامترهای ارسال شده به اجرای تزئینی مشابه پارامترهایی است که به تزئین کننده های اکسسوری ارسال شده است.

بیایید از همان دکوراتور قابل شمارش که قبلاً ایجاد کرده اید دوباره استفاده کنیم ، اما این بار در متد getFullName کلاس Person زیر:

const enumerable = (value: boolean) => {
  return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
    propertyDescriptor.enumerable = value;
  }
}

class Person {
  firstName: string = "Jon"
  lastName: string = "Doe"

  @enumerable(true)
  getFullName () {
    return `${this.firstName} ${this.lastName}`;
  }
}

اگر مقداری را از تزئین کننده متد خود برگردانده اید ، این مقدار به توصیف کننده جدید ویژگی متد تبدیل می شود.

بیایید یک دکوراتور منسوخ ایجاد کنیم که وقتی از متد استفاده می شود پیام ارسال شده را روی کنسول چاپ می کند و پیامی را ثبت می کند که می گوید این روش منسوخ شده است:

const deprecated = (deprecationReason: string) => {
  return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
    return {
      get() {
        const wrapperFn = (...args: any[]) => {
          console.warn(`Method ${memberName} is deprecated with reason: ${deprecationReason}`);
          propertyDescriptor.value.apply(this, args)
        }

        Object.defineProperty(this, memberName, {
            value: wrapperFn,
            configurable: true,
            writable: true
        });
        return wrapperFn;
      }
    }
  }
}

 

در اینجا ، شما در حال ایجاد یک تزئین کننده با استفاده از یک کارخانه تزئینات هستید. این کارخانه تزئینی یک آرگومان واحد از نوع string دریافت می کند ، که دلیل عدم استفاده از آن است ، همانطور که در قسمت برجسته زیر نشان داده شده است:

const deprecated = (deprecationReason: string) => {
  return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
    // ...
  }
}

deprecationReason بعداً هنگام ورود پیام منسوخ شدن به کنسول استفاده می شود. در اجرای تزئین منسوخ شده خود ، یک مقدار را برمی گردانید. هنگامی که مقداری را از یک تزئین کننده متد برمی گردانید ، این مقدار روی توصیف کننده ویژگی این عضو بازنویسی می کند.

شما از این مزیت استفاده می کنید تا متد را به روش کلاس تزئین شده خود اضافه کنید. به این ترتیب می توانید پیاده سازی خود روش را تغییر دهید.

اما چرا فقط از Object.defineProperty به جای بازگشت یک تزئین کننده جدید برای روش استفاده نکنید؟ این امر ضروری است زیرا باید به مقدار این دسترسی داشته باشید ، که برای روشهای کلاس غیر استاتیک ، به نمونه کلاس متصل است. اگر مستقیماً از Object.defineProperty استفاده می کنید ، هیچ راهی برای بازیابی مقدار آن برای شما وجود نخواهد داشت ، و اگر متدی که به هر نحوی از این روش استفاده می کرد ، تزئین کننده هنگام اجرای روش پیچیده شده از داخل اجرای تزئین کننده ، کد شما را می شکند.

در مورد شما ، خود گیرنده این مقدار را برای نمونه های غیراستاتیک به نمونه کلاس و برای متدهای استاتیک به سازنده کلاس محدود می کند.

در داخل getter شما سپس یک تابع wrapper به صورت محلی ایجاد می کنید ، به نام wrapperFn ، این تابع با استفاده از console یک پیام را به کنسول وارد می کند. هشدار دهید ، با رد deprecationReason دریافت شده از کارخانه decorator ، سپس با استفاده از propertyDescriptor.value روش اصلی را فراخوانی می کنید. apply (this، args) ، به این ترتیب متد اصلی نامیده می شود که این مقدار به درستی به نمونه کلاس متصل شده است در صورتی که یک روش غیر استاتیک بود.

سپس از definProperty برای بازنویسی مقدار متد خود در کلاس استفاده می کنید. این مانند یک مکانیسم یادآوری عمل می کند ، زیرا تماس های متعدد با یک روش دیگر با گیرنده شما تماس نمی گیرد ، بلکه مستقیماً با wrapperFn تماس می گیرد. اکنون شما با استفاده از Object.defineProperty ، عضو کلاس را طوری تنظیم می کنید که wrapperFn شما به عنوان مقدار آن باشد.

بیایید از دکوراتور منسوخ شده شما استفاده کنیم:

const deprecated = (deprecationReason: string) => {
  return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
    return {
      get() {
        const wrapperFn = (...args: any[]) => {
          console.warn(`Method ${memberName} is deprecated with reason: ${deprecationReason}`);
          propertyDescriptor.value.apply(this, args)
        }

        Object.defineProperty(this, memberName, {
            value: wrapperFn,
            configurable: true,
            writable: true
        });
        return wrapperFn;
      }
    }
  }
}

class TestClass {
  static staticMember = true;

  instanceMember: string = "hello"

  @deprecated("Use another static method")
  static deprecatedMethodStatic() {
    console.log('inside deprecated static method - staticMember =', this.staticMember);
  }

  @deprecated("Use another instance method")
  deprecatedMethod () {
    console.log('inside deprecated instance method - instanceMember =', this.instanceMember);
  }
}

TestClass.deprecatedMethodStatic();

const instance = new TestClass();
instance.deprecatedMethod();

در اینجا ، شما یک TestClass با دو ویژگی ایجاد کرده اید: یکی استاتیک و دیگری غیر استاتیک. شما همچنین دو روش ایجاد کرده اید: یکی استاتیک و دیگری غیر استاتیک.

سپس از تزئین کننده منسوخ خود برای هر دو روش استفاده می کنید. هنگام اجرای کد ، موارد زیر در کنسول ظاهر می شود:

 

Output

(warning) Method deprecatedMethodStatic is deprecated with reason: Use another static method
inside deprecated static method - staticMember = true
(warning)) Method deprecatedMethod is deprecated with reason: Use another instance method
inside deprecated instance method - instanceMember = hello

این نشان می دهد که هر دو روش به درستی با عملکرد wrapper شما بسته شده است ، که پیامی را با دلیل منسوخ شدن به کنسول وارد می کند.

اکنون شما اولین تزئین کننده متد خود را با استفاده از TypeScript ایجاد کرده اید. بخش بعدی نحوه ایجاد آخرین نوع تزئین کننده پشتیبانی شده توسط TypeScript ، یک تزئین کننده پارامتر را به شما نشان می دهد.

ایجاد پارامترهای Decorators

تزئینات پارامتری را می توان در پارامترهای روش کلاس استفاده کرد. در این بخش نحوه ایجاد آن را خواهید آموخت.

عملکرد تزئین کننده مورد استفاده با پارامترها پارامترهای زیر را دریافت می کند:

برای خواص استاتیک ، تابع سازنده کلاس. برای سایر خصوصیات ، نمونه اولیه کلاس.
نام عضو.
فهرست پارامترها در لیست پارامترهای متد.
تغییر هر چیزی که مربوط به خود پارامتر باشد امکان پذیر نیست ، بنابراین چنین تزئیناتی فقط برای مشاهده استفاده از خود پارامترها مفید هستند (مگر اینکه از موارد پیشرفته تری مانند بازتاب داده های بازتاب استفاده کنید).

در اینجا یک نمونه از تزئین کننده است که شاخص پارامتر تزئین شده را به همراه نام روش چاپ می کند:

function print(target: Object, propertyKey: string, parameterIndex: number) {
  console.log(`Decorating param ${parameterIndex} from ${propertyKey}`);
}

سپس می توانید پارامتر decorators خود را مانند این استفاده کنید:

class TestClass {
  testMethod(param0: any, @print param1: any) {}
}

اجرای کد بالا باید موارد زیر را در کنسول نمایش دهد:

 

Output

Decorating param 1 from testMethod

شما اکنون یک  پارامتر decorator ایجاد کرده و اجرا کرده اید و نتیجه ای را که شاخص پارامتر decorator را برمی گرداند چاپ می کنید.

نتیجه
در این آموزش ، شما تمام decorators پشتیبانی شده توسط TypeScript را پیاده سازی کرده اید ، از آنها در کلاس ها استفاده کرده اید و تفاوت های هر یک را یاد گرفته اید. اکنون می توانید برای کاهش کد صفحه بویلر در پایگاه کد خود ، نوشتن دکوراتورهای خود را شروع کنید ، یا با اطمینان بیشتر از دکوراتورهای کتابخانه هایی مانند Mobx استفاده کنید.

decoratorMethod DecoratorsProperty DecoratorsTypeScriptپارامترهای Decoratorsجاواجاوا اسکریپتسرورسرور مجازیکامپایلر TypeScript

  • behnam gol mohamadi
  • ۰
  • ۰

راه اندازی سرور اولیه با Rocky Linux 8

ورود به سایت

معرفی

هنگامی که برای اولین بار سرور جدید Rocky Linux 8 ایجاد می کنید ، چند مرحله پیکربندی وجود دارد که باید به عنوان بخشی از تنظیمات اولیه ، اوایل آن را انجام دهید. این امر امنیت و قابلیت استفاده از سرور شما را افزایش می دهد و پایه محکمی برای اقدامات بعدی به شما می دهد.

مرحله 1 – ورود به سیستم به عنوان Root

برای ورود به سرور خود ، باید آدرس IP عمومی سرور خود را بدانید. شما همچنین به رمز عبور یا اگر یک کلید SSH برای احراز هویت نصب کرده اید ، به کلید خصوصی حساب کاربر اصلی نیاز دارید. اگر قبلاً به سرور خود وارد نشده اید ، ممکن است بخواهید اسناد ما را در مورد نحوه اتصال به Droplet خود با SSH دنبال کنید ، که این فرآیند را با جزئیات پوشش می دهد.

اگر قبلاً به سرور خود متصل نیستید ، اکنون با استفاده از دستور زیر به عنوان کاربر اصلی وارد شوید (قسمت برجسته شده فرمان را با آدرس IP عمومی سرور خود جایگزین کنید):

ssh root@your_server_ip

در صورت ظاهر شدن هشدار مربوط به اصالت میزبان را بپذیرید. اگر از احراز هویت رمز عبور استفاده می کنید ، رمز ورود خود را برای ورود وارد کنید. اگر از کلید SSH که از رمز عبور محافظت می کند استفاده می کنید ، ممکن است از شما خواسته شود که اولین بار که از کلید در هر جلسه استفاده می کنید عبارت عبور را وارد کنید. اگر برای اولین بار است که با گذرواژه وارد سرور می شوید ، ممکن است از شما خواسته شود که رمز اصلی را تغییر دهید.

درباره Root

کاربر اصلی کاربر اداری در یک محیط لینوکس است و دارای امتیازات بسیار وسیعی است. به دلیل افزایش امتیازات حساب اصلی ، از استفاده منظم آن دلسرد می شوید. این به این دلیل است که بخشی از قدرت ذاتی حساب اصلی ، توانایی ایجاد تغییرات بسیار مخرب ، حتی به طور تصادفی است.

به این ترتیب ، گام بعدی این است که یک حساب کاربری جایگزین با دامنه نفوذ کاهش یافته برای کارهای روزمره ایجاد کنید. این حساب همچنان می تواند در صورت لزوم امتیازات بیشتری را به دست آورد.

مرحله 2 – ایجاد یک کاربر جدید

پس از ورود به سیستم root ، می توانید حساب کاربری جدیدی ایجاد کنید که از این پس برای ورود به سیستم از آن استفاده می کنیم.

این مثال یک کاربر جدید به نام sammy ایجاد می کند ، اما شما باید نام کاربری دیگری را که ترجیح می دهید جایگزین کنید:

adduser sammy

در مرحله بعد ، یک رمز عبور قوی برای کاربر sammy تعیین کنید:

passwd sammy

دوبار از شما خواسته می شود که رمز عبور را وارد کنید. پس از انجام این کار ، کاربر شما آماده استفاده می شود ، اما ابتدا به این کاربر امتیازات بیشتری می دهیم تا از دستور sudo استفاده کند. این به ما اجازه می دهد تا در صورت لزوم دستورات را به عنوان root اجرا کنیم

مرحله 3 – اعطای امتیازات اداری

اکنون ، ما یک حساب کاربری جدید با امتیازات حساب معمولی داریم. با این حال ، ممکن است گاهی اوقات نیاز به انجام کارهای اداری داشته باشیم.

برای اجتناب از خروج از کاربر معمولی و ورود مجدد به عنوان حساب اصلی ، می توانیم مواردی را که به عنوان “superuser” یا امتیازات root برای حساب معمولی خود شناخته می شود ، تنظیم کنیم. این به کاربر معمولی ما این امکان را می دهد که با قرار دادن کلمه sudo قبل از هر فرمان ، فرمان هایی با امتیاز مدیریتی اجرا کند.

برای افزودن این امتیازات به کاربر جدید ، باید کاربر جدید را به گروه چرخ اضافه کنیم. به طور پیش فرض ، در Rocky Linux 8 ، کاربرانی که به گروه چرخ تعلق دارند مجاز به استفاده از دستور sudo هستند.

به عنوان root ، این دستور را اجرا کنید تا کاربر جدید خود را به گروه چرخ اضافه کنید (کلمه برجسته شده را با نام کاربری جدید خود جایگزین کنید):

usermod -aG wheel sammy

اکنون ، هنگامی که به عنوان کاربر معمولی خود وارد سیستم شده اید ، می توانید sudo را قبل از دستورات برای انجام اقدامات با امتیازات فوق العاده کاربر تایپ کنید.

مرحله 4 – راه اندازی یک فایروال اساسی

فایروال ها سطح اولیه امنیت را برای سرور شما فراهم می کنند. این برنامه ها مسئول جلوگیری از تردد به هر پورت سرور شما هستند ، به جز درگاه ها/سرویس هایی که صراحتاً تأیید کرده اید. راکی لینوکس برای انجام این عملکرد سرویسی به نام firewalld دارد. ابزاری به نام firewall-cmd برای پیکربندی خط مشی های دیوار آتش استفاده می شود

ابتدا firewalld را نصب کنید:

dnf install firewalld -y

پیکربندی پیش فرض firewalld اجازه اتصال ssh را می دهد ، بنابراین می توانیم فایروال را بلافاصله روشن کنیم

systemctl start firewalld

برای اطمینان از شروع سرویس ، وضعیت آن را بررسی کنید:

systemctl status firewalld

 

Output

● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2020-02-06 16:39:40 UTC; 3s ago
     Docs: man:firewalld(1)
 Main PID: 13180 (firewalld)
    Tasks: 2 (limit: 5059)
   Memory: 22.4M
   CGroup: /system.slice/firewalld.service
           └─13180 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid

توجه داشته باشید که هم فعال است و هم فعال ، یعنی اگر سرور راه اندازی مجدد شود به طور پیش فرض شروع می شود.

اکنون که سرویس راه اندازی شده است ، می توانیم از برنامه firewall-cmd برای بدست آوردن و تنظیم اطلاعات خط مشی برای فایروال استفاده کنیم.

ابتدا بیایید فهرست کنیم که کدام سرویس ها قبلاً مجاز هستند:

firewall-cmd –permanent –list-all

 

Output

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

برای مشاهده خدمات اضافی که می توانید با نام آنها را فعال کنید ، تایپ کنید:

firewall-cmd –get-services

برای افزودن سرویسی که باید مجاز باشد ، از پرچم –add-service استفاده کنید:

firewall-cmd –permanent –add-service=http

با این کار سرویس http اضافه می شود و ترافیک ورودی TCP به پورت 80 امکان پذیر می شود. پیکربندی پس از بارگیری مجدد فایروال به روز می شود:

firewall-cmd –reload

به یاد داشته باشید که برای هرگونه سرویس اضافی که بعداً ممکن است پیکربندی کنید ، باید فایروال (با سرویس یا پورت) را به صراحت باز کنید.

مرحله 5 – فعال کردن دسترسی خارجی برای کاربر معمولی خود

اکنون که یک کاربر معمولی غیر روت برای استفاده روزانه داریم ، باید مطمئن شویم که می توانیم از آن برای SSH در سرور خود استفاده کنیم.

فرایند پیکربندی دسترسی SSH برای کاربر جدید شما بستگی به این دارد که حساب ریشه سرور شما از رمز عبور یا کلیدهای SSH برای احراز هویت استفاده کند.

اگر حساب Root از احراز هویت رمز عبور استفاده می کند

اگر با استفاده از رمز عبور وارد حساب اصلی خود شده اید ، احراز هویت رمز عبور برای SSH فعال است. می توانید با باز کردن یک جلسه ترمینال جدید و استفاده از SSH با نام کاربری جدید خود ، به حساب کاربری جدید خود SSH وارد کنید:

ssh sammy@your_server_ip

پس از وارد کردن گذرواژه کاربر معمولی خود ، وارد سیستم می شوید. به یاد داشته باشید ، اگر نیاز به اجرای فرمان با مجوزهای مدیریتی دارید ، قبل از آن sudo را به این شکل تایپ کنید:

sudo command_to_run

هنگام استفاده از sudo برای اولین بار در هر جلسه (و دوره ای پس از آن) از شما رمز عبور معمولی کاربر درخواست می شود.

برای افزایش امنیت سرور ، توصیه می کنیم به جای استفاده از احراز هویت رمز عبور ، کلیدهای SSH را تنظیم کنید. برای آموزش نحوه پیکربندی احراز هویت مبتنی بر کلید ، راهنمای ما را در مورد تنظیم کلیدهای SSH در Rocky Linux 8 دنبال کنید.

اگر حساب Root از احراز هویت کلید SSH استفاده می کند

اگر با استفاده از کلیدهای SSH وارد حساب اصلی خود شده اید ، احراز هویت رمز عبور برای SSH غیرفعال است. برای ورود موفق به سیستم ، باید یک نسخه از کلید عمومی خود را به فایل user/.ssh/author_keys کاربر جدید اضافه کنید.

از آنجا که کلید عمومی شما قبلاً در فایل root/.ssh/author_keys حساب ریشه در سرور است ، می توانیم آن فایل و ساختار فهرست را در حساب کاربری جدید خود کپی کنیم.

ساده ترین راه برای کپی فایل ها با مالکیت و مجوزهای صحیح ، دستور rsync است. این کار دایرکتوری .ssh کاربر اصلی را کپی می کند ، مجوزها را حفظ می کند و صاحبان فایل را در یک فرمان واحد تغییر می دهد. اطمینان حاصل کنید که قسمت های برجسته فرمان زیر را برای مطابقت با نام کاربر معمولی خود تغییر دهید:

rsync –archive –chown=sammy:sammy ~/.ssh /home/sammy

اکنون ، در یک ترمینال جدید در دستگاه محلی خود ، یک جلسه SSH جدید را با کاربر غیر root خود باز کنید:

ssh sammy@your_server_ip

شما باید بدون استفاده از رمز عبور وارد حساب کاربری جدید شوید. به یاد داشته باشید ، اگر نیاز به اجرای یک فرمان با امتیازات مدیریتی دارید ، قبل از آن sudo را به این شکل تایپ کنید:

sudo command_to_run

هنگام استفاده از sudo برای اولین بار در هر جلسه (و دوره ای پس از آن) از شما رمز عبور معمولی کاربر درخواست می شود.

نتیجه

در این مرحله ، شما یک پایه محکم برای سرور خود دارید. هم اکنون می توانید هر یک از نرم افزارهای مورد نیاز خود را بر روی سرور خود نصب کنید.

Rocky Linux 8rootجدیدترین سرور لینوکسخرید سرور لینوکسراه اندازی فایروالسرور لینوکسسرورRocky Linux 8

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه تنظیم کلیدهای SSH در Rocky Linux 8

ورود به سایت

معرفی

SSH یا پوسته امن ، یک پروتکل رمزگذاری شده است که برای مدیریت و ارتباط با سرورها استفاده می شود. هنگام کار با سرور لینوکس راکی ، به احتمال زیاد بیشتر وقت خود را در جلسه ترمینال متصل به سرور خود از طریق SSH خواهید گذراند.

در این راهنما ، ما بر تنظیم کلیدهای SSH برای سرور Rocky Linux 8 تمرکز می کنیم. کلیدهای SSH یک روش ساده و ایمن برای ورود به سرور شما ارائه می دهند و برای همه کاربران توصیه می شود.

مرحله 1 – ایجاد جفت کلید RSA

اولین قدم ایجاد یک جفت کلید در ماشین سرویس گیرنده (معمولاً رایانه محلی شما) است:

ssh-keygen

به طور پیش فرض ، ssh-keygen یک جفت کلید RSA 2048 بیتی ایجاد می کند ، که برای اکثر موارد استفاده از امنیت کافی برخوردار است (برای ایجاد یک کلید بزرگتر 4096 می توانید به صورت اختیاری در پرچم -b 4096 قرار دهید).

پس از وارد کردن فرمان ، باید اعلان زیر را مشاهده کنید:

Output
Generating public/private rsa key pair.
Enter file in which to save the key (/your_home/.ssh/id_rsa):

ENTER را فشار دهید تا جفت کلید در .ssh/ subdirectory در فهرست اصلی ذخیره شود ، یا یک مسیر جایگزین مشخص کنید.

اگر قبلاً یک جفت کلید SSH ایجاد کرده اید ، ممکن است درخواست زیر را مشاهده کنید:

Output
/home/your_home/.ssh/id_rsa already exists.
Overwrite (y/n)?

در صورت انتخاب بازنویسی کلید روی دیسک ، دیگر نمی توانید با استفاده از کلید قبلی احراز هویت کنید. هنگام انتخاب بله بسیار مراقب باشید ، زیرا این یک روند مخرب است که قابل برگشت نیست.

سپس باید اعلان زیر را مشاهده کنید:

Output
Enter passphrase (empty for no passphrase):

در اینجا می توانید به صورت اختیاری یک رمز عبور امن وارد کنید ، که بسیار توصیه می شود. عبارت عبور یک لایه امنیتی اضافی به کلید شما می افزاید تا از ورود کاربران غیر مجاز به سیستم جلوگیری کند.

سپس باید خروجی زیر را مشاهده کنید:

 

Output

Your identification has been saved in /your_home/.ssh/id_rsa.
Your public key has been saved in /your_home/.ssh/id_rsa.pub.
The key fingerprint is:
a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_host
The key's randomart image is:
+--[ RSA 2048]----+
|     ..o         |
|   E o= .        |
|    o. o         |
|        ..       |
|      ..S        |
|     o o.        |
|   =o.+.         |
|. =++..          |
|o=++.            |
+-----------------+

 

اکنون یک کلید عمومی و خصوصی دارید که می توانید از آن برای احراز هویت استفاده کنید. مرحله بعدی این است که کلید عمومی را به سرور خود وارد کنید تا بتوانید از سیستم احراز هویت مبتنی بر کلید SSH برای ورود به سیستم استفاده کنید.

مرحله 2 – کپی کلید عمومی در سرور لینوکس سنگی خود

سریعترین راه برای کپی کردن کلید عمومی در میزبان Rocky Linux استفاده از ابزاری به نام ssh-copy-id است. این روش در صورت وجود بسیار توصیه می شود. اگر ssh-copy-id را در دستگاه مشتری خود در اختیار ندارید ، می توانید از یکی از دو روش جایگزین زیر استفاده کنید (کپی از طریق SSH مبتنی بر رمز عبور ، یا کپی دستی کلید).

کپی کلید عمومی خود با استفاده از ssh-copy-id

ابزار ssh-copy-id به طور پیش فرض در بسیاری از سیستم عامل ها گنجانده شده است ، بنابراین ممکن است آن را در سیستم محلی خود در دسترس داشته باشید. برای اینکه این روش کار کند ، باید از قبل دسترسی SSH مبتنی بر گذرواژه به سرور خود داشته باشید.

برای استفاده از این ابزار ، فقط باید میزبان از راه دور که می خواهید به آن متصل شوید و حساب کاربری که رمز عبور SSH به آن دسترسی دارید را مشخص کنید. این حسابی است که کلید SSH عمومی شما در آن کپی می شود:

ssh-copy-id username@remote_host

ممکن است پیام زیر را مشاهده کنید:

 

Output

The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

این بدان معناست که رایانه محلی شما میزبان از راه دور را تشخیص نمی دهد. این اولین باری است که به میزبان جدید متصل می شوید. بله را تایپ کنید و ENTER را برای ادامه فشار دهید.

در مرحله بعد ، برنامه حساب محلی شما را برای کلید id_rsa.pub که قبلاً ایجاد کرده ایم اسکن می کند. هنگامی که کلید را پیدا کرد ، از شما رمز عبور حساب کاربر از راه دور را درخواست می کند:

 

Output

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
username@203.0.113.1's password:

رمز عبور را وارد کنید (تایپ شما برای اهداف امنیتی نمایش داده نمی شود) و ENTER را فشار دهید. این ابزار با استفاده از گذرواژه ای که ارائه کرده اید به حساب موجود در میزبان راه دور متصل می شود. سپس محتویات کلید ~/.ssh/id_rsa.pub شما را در فایل remote/.ssh/author_keys حساب از راه دور کپی می کند.

شما باید خروجی زیر را مشاهده کنید:

 

Output

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'username@203.0.113.1'"
and check to make sure that only the key(s) you wanted were added.

در این مرحله ، کلید id_rsa.pub شما در حساب راه دور بارگذاری شده است. می توانید به مرحله 3 ادامه دهید.

کپی کلید عمومی با استفاده از SSH

اگر ssh-copy-id در دسترس ندارید ، اما دسترسی SSH مبتنی بر رمز عبور به یک حساب کاربری در سرور خود دارید ، می توانید کلیدهای خود را با استفاده از یک روش مرسوم SSH بارگذاری کنید.

ما می توانیم این کار را با استفاده از دستور cat برای خواندن محتویات کلید عمومی SSH در رایانه محلی خود و پیپ کردن آن از طریق اتصال SSH به سرور راه دور انجام دهیم.

از طرف دیگر ، می توانیم مطمئن شویم که فهرست ~/.ssh وجود دارد و دارای مجوزهای صحیح تحت حساب مورد استفاده ما است.

سپس می توانیم محتوایی را که پیپ کرده ایم در فایلی به نام author_keys در این دایرکتوری خروجی دهیم. ما برای افزودن محتوا به جای بازنویسی از نماد تغییر مسیر >> استفاده می کنیم. این به ما اجازه می دهد کلیدها را بدون از بین بردن کلیدهای قبلی اضافه شده اضافه کنیم.

دستور کامل به این شکل است:

cat ~/.ssh/id_rsa.pub | ssh username@remote_host “mkdir -p ~/.ssh && touch ~/.ssh/authorized_keys && chmod -R go= ~/.ssh && cat >> ~/.ssh/authorized_keys”

ممکن است پیام زیر را مشاهده کنید:

 

Output

The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

 

این بدان معناست که رایانه محلی شما میزبان از راه دور را تشخیص نمی دهد. این اولین باری است که به میزبان جدید متصل می شوید. بله را تایپ کنید و ENTER را برای ادامه فشار دهید.

پس از آن ، باید از شما خواسته شود که گذرواژه حساب کاربری از راه دور را وارد کنید:

 

Output

username@203.0.113.1's password:

پس از وارد کردن گذرواژه خود ، محتوای کلید id_rsa.pub شما در انتهای فایل مجاز_keys حساب کاربر از راه دور کپی می شود. در صورت موفقیت آمیز بودن مرحله 3 را ادامه دهید.

کپی کلید عمومی به صورت دستی

اگر دسترسی SSH مبتنی بر رمز عبور به سرور خود ندارید ، باید مراحل بالا را به صورت دستی تکمیل کنید.

ما به صورت دستی محتوای فایل id_rsa.pub شما را به فایل ~/.ssh/author_keys در دستگاه راه دور خود اضافه می کنیم.

برای نمایش محتوای کلید id_rsa.pub خود ، این را در رایانه محلی خود تایپ کنید:

cat ~/.ssh/id_rsa.pub

محتوای کلید را مشاهده خواهید کرد ، که باید چیزی شبیه به این باشد:

 

Output

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== sammy@host

با استفاده از هر روشی که در دسترس دارید ، وارد میزبان راه دور خود شوید.

پس از دسترسی به حساب خود در سرور راه دور ، باید مطمئن شوید که فهرست ~/.ssh وجود دارد. این دستور در صورت لزوم دایرکتوری را ایجاد می کند یا در صورت وجود هیچ کاری انجام نمی دهد:

mkdir -p ~/.ssh

اکنون ، می توانید فایل author_keys را در این فهرست ایجاد یا اصلاح کنید. می توانید محتویات فایل id_rsa.pub خود را به انتهای فایل author_keys اضافه کنید و در صورت لزوم آن را با استفاده از این دستور ایجاد کنید:

echo public_key_string >> ~/.ssh/authorized_keys

در دستور بالا ، public_key_string را با خروجی دستور cat ~/.ssh/id_rsa.pub که در سیستم محلی خود اجرا کرده اید جایگزین کنید. باید با ssh-rsa AAAA شروع شود ….

در نهایت ، ما اطمینان حاصل می کنیم که دایرکتوری./.ssh و فایل author_keys دارای مجوزهای مناسب هستند:

chmod -R go= ~/.ssh

با این کار همه مجوزهای “گروه” و “دیگر” برای فهرست ~/ .ssh/ حذف می شود.

اگر از حساب اصلی برای تنظیم کلیدها برای یک حساب کاربری استفاده می کنید ، همچنین مهم است که فهرست ~/.ssh متعلق به کاربر باشد و نه روت:

chown -R sammy:sammy ~/.ssh

در این آموزش کاربر ما sammy نامیده می شود اما شما باید نام کاربری مناسب را در دستور بالا جایگزین کنید.

اکنون می توانیم با سرور Linux Rocky خود احراز هویت مبتنی بر کلید را انجام دهیم.

مرحله 3 – ورود به سرور سنگی لینوکس خود با استفاده از کلیدهای SSH

اگر یکی از مراحل بالا را با موفقیت انجام داده اید ، اکنون باید بتوانید بدون گذرواژه حساب راه دور وارد میزبان راه دور شوید.

فرایند اولیه مشابه احراز هویت مبتنی بر رمز عبور است:

ssh username@remote_host

اگر برای اولین بار است که به این میزبان وصل می شوید (اگر از آخرین روش بالا استفاده کرده اید) ، ممکن است چیزی شبیه به این را مشاهده کنید:

 

Output

The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

این بدان معناست که رایانه محلی شما میزبان از راه دور را تشخیص نمی دهد. بله را تایپ کنید و سپس ENTER را برای ادامه فشار دهید.

اگر هنگام ایجاد جفت کلید خود در مرحله 1 یک رمز عبور ارائه نکرده اید ، بلافاصله وارد سیستم می شوید. اگر یک عبارت عبور ارائه کرده اید ، از شما خواسته می شود که آن را وارد کنید. پس از احراز هویت ، یک جلسه پوسته جدید باید با حساب پیکربندی شده در سرور Rocky Linux برای شما باز شود.

اگر احراز هویت مبتنی بر کلید موفقیت آمیز بود ، به نحوه یادگیری نحوه ایمن سازی بیشتر سیستم خود با غیرفعال کردن احراز هویت مبتنی بر رمز عبور سرور SSH خود ادامه دهید.

مرحله 4 – غیرفعال کردن احراز هویت رمز عبور در سرور خود

اگر می توانید بدون استفاده از SSH به حساب خود وارد شوید ، احراز هویت مبتنی بر کلید SSH را با موفقیت پیکربندی کرده اید. با این حال ، مکانیزم احراز هویت مبتنی بر رمز عبور شما هنوز فعال است ، به این معنی که سرور شما هنوز در معرض حملات بی رحمانه است.

قبل از اتمام مراحل این بخش ، مطمئن شوید که یا احراز هویت مبتنی بر کلید SSH برای حساب ریشه در این سرور پیکربندی شده است ، یا ترجیحاً احراز هویت مبتنی بر کلید SSH برای یک حساب غیر ریشه در این پیکربندی شده است. سرور دارای امتیازات sudo این مرحله ورودهای مبتنی بر گذرواژه را قفل می کند ، بنابراین اطمینان از این که هنوز می توانید دسترسی اداری داشته باشید بسیار مهم است.

هنگامی که تأیید کردید که حساب راه دور شما دارای امتیازات مدیریتی است ، با کلیدهای SSH وارد سرور راه دور خود شوید ، یا به صورت root یا با حسابی با امتیازات sudo. سپس ، فایل پیکربندی SSH daemon را باز کنید:

sudo vi /etc/ssh/sshd_config

در داخل فایل ، دستورالعملی به نام PasswordAuthentication را جستجو کنید. این ممکن است با یک # هش نظر داده شود. i را فشار دهید تا vi در حالت درج قرار گیرد ، و سپس خط را کامنت نکنید و مقدار را روی no قرار دهید. با این کار امکان ورود به سیستم از طریق SSH با استفاده از گذرواژه های حساب غیرفعال می شود:


PasswordAuthentication no

پس از اتمام اعمال تغییرات ، ESC و سپس: wq را فشار دهید تا تغییرات را در فایل بنویسید و خارج شوید. برای پیاده سازی واقعی این تغییرات ، باید سرویس sshd را راه اندازی مجدد کنیم:

sudo systemctl restart sshd

برای احتیاط ، یک پنجره ترمینال جدید باز کنید و قبل از بستن جلسه فعلی خود ، صحت عملکرد سرویس SSH را بررسی کنید:

ssh username@remote_host

هنگامی که تأیید کردید که سرویس SSH شما هنوز به درستی کار می کند ، می توانید با خیال راحت تمام جلسات سرور فعلی را ببندید.

الگوی SSH در سرور Linux Rocky شما اکنون فقط به کلیدهای SSH پاسخ می دهد. احراز هویت مبتنی بر رمز عبور با موفقیت غیرفعال شد.

خرید سرور لینوکسسرورسرور Rocky Linux 8سرور سنگی لینوکسسرور لینوکسفروش سرورکلیدهای SSHلینوکس

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه مدیریت داده های زیرساخت با خروجی های Terraform

ورود به سایت

 

معرفی

خروجی های Terraform برای استخراج اطلاعات مربوط به منابع زیرساخت از حالت پروژه استفاده می شود. با استفاده از سایر ویژگی های زبان پیکربندی Hashicorp (HCL) ، که Terraform از آن استفاده می کند ، می توان اطلاعات منابع را جستجو کرد و به ساختارهای داده پیچیده تری مانند لیست ها و نقشه ها تبدیل کرد. خروجی ها برای ارائه اطلاعات به نرم افزارهای خارجی مفید هستند که می توانند بر روی منابع زیرساخت ایجاد شده کار کنند.

در این آموزش ، با نحوی خروجی Terraform و پارامترهای آن با ایجاد یک زیرساخت ساده که Droplets را مستقر می کند ، آشنا خواهید شد. شما همچنین می توانید خروجی ها را به صورت برنامه نویسی با تبدیل به JSON تجزیه کنید.

پیش نیازها

توکن vpsgol Personal Access Token ، که می توانید از طریق کنترل پنل vpsgol ایجاد کنید. دستورالعمل انجام این کار را می توانید در این پیوند مشاهده کنید: نحوه ایجاد یک رمز دسترسی شخصی.
Terraform بر روی دستگاه محلی شما نصب شده و پروژه ای با ارائه دهنده vpsgol تنظیم شده است. مرحله 1 و مرحله 2 نحوه استفاده از Terraform با vpsgol را تکمیل کنید و مطمئن شوید که پوشه پروژه را terraform-outputs ، به جای loadbalance نامگذاری کنید. در مرحله 2 ، متغیر pvt_key و منبع کلید SSH را وارد نکنید.
آشنایی با انواع داده ها و حلقه های HCL. برای اطلاعات بیشتر ، آموزش نحوه بهبود انعطاف پذیری با استفاده از متغیرهای Terraform ، وابستگی ها و شرایط را مشاهده کنید.

توجه: این آموزش به طور خاص با Terraform 1.0.2 آزمایش شده است.

تعریف خروجی ها

در این بخش ، یک Droplet را اعلام می کنید ، آن را در ابر مستقر می کنید و با تعیین خروجی هایی که آدرس IP Droplet را نشان می دهد ، با خروجی ها آشنا می شوید.

از فهرست راهنمای terraform-outputs که به عنوان پیش نیاز ایجاد کرده اید ، فایل droplets.tf را برای ویرایش ایجاد کرده و باز کنید:

nano droplets.tf

منبع Droplet و تعریف خروجی زیر را اضافه کنید:

terraform-outputs/droplets.tf

resource “vpsgol_droplet” “web” { image = “ubuntu-20-04-x64” name = “test-droplet” region = “fra1” size = “s-1vcpu-1gb” } output “droplet_ip_address” { value = vpsgol_droplet.web.ipv4_address }

ابتدا یک منبع Droplet به نام وب اعلام کنید. نام واقعی آن در ابر به صورت قطره ای و در منطقه fra1 با اوبونتو 20.04 اجرا می شود.

سپس ، خروجی ای به نام droplet_ip_address اعلام می کنید. در Terraform ، خروجی ها برای صادرات و نشان دادن مقادیر داخلی و محاسبه شده و اطلاعات مربوط به منابع استفاده می شوند. در اینجا ، پارامتر مقدار را که داده را به خروجی می پذیرد ، روی آدرس IP قطره اعلام شده تنظیم می کنید. در زمان اعلام ، نامشخص است ، اما پس از استقرار Droplet در دسترس قرار می گیرد. خروجی ها بعد از هر بار استقرار نشان داده می شوند و قابل دسترسی هستند.

فایل را ذخیره و ببندید ، سپس پروژه را با اجرای دستور زیر مستقر کنید:

terraform apply -var “do_token=${DO_PAT}”

برای درخواست در صورت درخواست ، بله را وارد کنید. انتهای خروجی مشابه این خواهد بود:

Output…
vpsgol_droplet.web: Creating…

vpsgol_droplet.web: Creation complete after 32s [id=207631771]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

droplet_ip_address = ip_address

 

آدرس IP برجسته متعلق به Droplet جدید شماست. با استفاده از پروژه منابع را روی ابر مستقر می کند و خروجی ها را در پایان نشان می دهد ، زمانی که همه ویژگی های منبع در دسترس هستند. بدون خروجی droplet_ip_address ، Terraform اطلاعات بیشتری در مورد Droplet نشان نمی دهد ، مگر اینکه مستقر باشد.

خروجی ها را نیز می توان با استفاده از دستور خروجی نشان داد:

terraform output

خروجی تمام خروجی های پروژه را لیست می کند:

Output

droplet_ip_address = ip_address

همچنین می توانید یک خروجی خاص را با نام و با تعیین آن به عنوان یک آرگومان ، درخواست کنید:

terraform output output_name

برای droplet_ip_address ، خروجی فقط شامل آدرس IP است:

Output
ip_address

به جز تعیین مقدار اجباری ، خروجی ها دارای چند پارامتر اختیاری هستند:

توضیحات: مستندات کوتاهی را با جزئیات آنچه خروجی نشان می دهد ، جاسازی می کند.
varet_on: یک پارامتر متا در هر منبع موجود است که به شما امکان می دهد منابع را به طور صریح مشخص کنید که خروجی بستگی به این دارد که Terraform قادر نیست در طول برنامه ریزی به طور خودکار نتیجه گیری کند.
حساس: مقدار بولین را می پذیرد ، که در صورت تنظیم روی true از نمایش محتوای خروجی پس از استقرار جلوگیری می کند.
پارامتر حساس زمانی مفید است که سیاهههای مربوط به استقرار Terraform در دسترس عموم قرار گیرد ، اما محتویات خروجی باید مخفی نگه داشته شوند. اکنون آن را به تعریف منابع Droplet خود اضافه می کنید.

droplets.tf را برای ویرایش باز کرده و خط برجسته را اضافه کنید:

resource “vpsgol_droplet” “web” {
image = “ubuntu-20-04-x64”
name = “test-droplet”
region = “fra1”
size = “s-1vcpu-1gb”
}

output “droplet_ip_address” {
value = vpsgol_droplet.web.ipv4_address
sensitive = true
}

پس از اتمام کار فایل را ذخیره و ببندید. دوباره پروژه را با اجرای زیر اجرا کنید:

terraform apply -var “do_token=${DO_PAT}”

در صورت درخواست بله را وارد کنید. خواهید دید که خروجی تغییر یافته است:

Output…

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

droplet_ip_address = <sensitive>

حتی اگر به عنوان حساس علامت گذاری شده باشد ، خروجی و محتویات آن همچنان از طریق کانال های دیگر مانند مشاهده وضعیت Terraform یا پرسیدن مستقیم خروجی ها در دسترس خواهد بود.

در مرحله بعد ، یک ساختار Droplet و خروجی متفاوت ایجاد می کنید ، بنابراین با اجرای موارد زیر ، ساختارهای فعلی را از بین ببرید:

terraform destroy -var “do_token=${DO_PAT}”

خروجی در انتها خواهد بود:

Output

… Destroy complete! Resources: 1 destroyed.

شما یک Droplet را اعلام و مستقر کرده و خروجی ایجاد کرده اید که آدرس IP آن را نشان می دهد. اکنون با استفاده از خروجی ها برای نشان دادن ساختارهای پیچیده تر مانند لیست ها و نقشه ها آشنا خواهید شد.

خروجی سازه های پیچیده

در این بخش ، با استفاده از کلمه کلیدی count ، چند قطره از یک تعریف را مستقر کرده و آدرس IP آنها را در قالب های مختلف خروجی می دهید.

با استفاده از حلقه for

شما باید تعریف منبع Droplet را تغییر دهید ، بنابراین آن را برای ویرایش باز کنید:

nano droplets.tf

آن را اصلاح کنید تا به این شکل باشد:

resource “vpsgol_droplet” “web” {
count = 3
image = “ubuntu-20-04-x64”
name = “test-droplet-${count.index}”
region = “fra1”
size = “s-1vcpu-1gb”
}

شما مشخص کرده اید که سه قطره باید با استفاده از کلید شمارش ایجاد شود و فهرست فعلی را به نام قطره اضافه کنید ، تا بعداً بتوانید بین آنها تشخیص دهید. خروجی موجود زیر را حذف کنید. پس از اتمام کار ، فایل را ذخیره و ببندید.

کد را با اجرای زیر اعمال کنید:

terraform apply -var “do_token=${DO_PAT}”

Terraform برنامه ای برای ایجاد سه قطره شماره دار به نام های test-droplet-0 ، test-droplet-1 و test-droplet-2 خواهد داشت. وقتی از شما خواسته شد تا مراحل را به پایان برسانید بله را وارد کنید. در پایان خروجی زیر را مشاهده خواهید کرد:


Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

این بدان معناست که هر سه Droplets با موفقیت مستقر شده اند و تمام اطلاعات مربوط به آنها در حالت پروژه ذخیره می شود.

ساده ترین راه برای دسترسی به ویژگی های منابع آنها استفاده از خروجی ها است ، اما ایجاد یکی برای هر Droplet مقیاس پذیر نیست. راه حل این است که از حلقه for برای عبور از لیست Droplets و جمع آوری ویژگی های آنها استفاده کنید ، یا از عبارت های splat استفاده کنید (که بعداً در این مرحله با آنها آشنا خواهید شد).

ابتدا یک خروجی تعریف می کنید که آدرس IP سه قطره را با نام آنها جفت می کند. droplets.tf را برای ویرایش باز کنید:

nano droplets.tf

خطوط زیر را اضافه کنید:

resource “vpsgol_droplet” “web” {
count = 3
image = “ubuntu-20-04-x64”
name = “test-droplet-${count.index}”
region = “fra1”
size = “s-1vcpu-1gb”
}

output “droplet_ip_addresses” {
value = {
for droplet in vpsgol_droplet.web:
droplet.name => droplet.ipv4_address
}
}

مقدار خروجی droplet_ip_addresses با استفاده از حلقه for ساخته می شود. از آنجا که توسط براکت احاطه شده است ، نوع حاصله یک نقشه خواهد بود. حلقه از لیست Droplets عبور می کند و برای هر نمونه ، نام آن را با آدرس IP آن جفت می کند و آن را به نقشه حاصل می افزاید.

فایل را ذخیره و ببندید ، سپس پروژه را دوباره اعمال کنید:

terraform apply -var “do_token=${DO_PAT}”

در صورت درخواست بله را وارد کنید و در پایان محتویات خروجی را دریافت خواهید کرد:

OutputApply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

droplet_ip_addresses = {
“test-droplet-0” = “ip_address”
“test-droplet-1” = “ip_address”
“test-droplet-2” = “ip_address”
}

droplet_ip_addresses آدرس IP سه قطره مستقر شده را مشخص می کند.

با استفاده از فرمان خروجی Terraform ، می توانید محتویات خروجی را به عنوان JSON با استفاده از آرگومان فرمان آن دریافت کنید:

terraform output -json droplet_ip_addresses

نتیجه مشابه موارد زیر خواهد بود:

Output{“test-droplet-0″:”ip_address”,”test-droplet-1″:”ip_address”,”test-droplet-2″:”ip_address”}

تجزیه JSON به طور گسترده ای در بسیاری از زبان های برنامه نویسی مورد استفاده قرار می گیرد و پشتیبانی می شود. به این ترتیب ، می توانید به طور برنامه ای اطلاعات مربوط به منابع Droplet مستقر را تجزیه کنید.

استفاده از عبارت Splat

عبارات Splat یک روش جمع و جور برای تکرار در تمام عناصر یک لیست و جمع آوری محتویات یک ویژگی از هر یک از آنها را ارائه می دهد که منجر به ایجاد یک لیست می شود. یک عبارت splat که آدرس IP سه قطره مستقر را استخراج می کند دارای نحو زیر است:

vpsgol_droplet.web[*].ipv4_address

نماد [*] از فهرست سمت چپ خود می گذرد و برای هر یک از عناصر ، محتویات ویژگی مشخص شده در سمت راست را می گیرد. اگر مرجع در سمت چپ به خودی خود یک لیست نباشد ، به یکی تبدیل می شود که تنها عنصر باشد.

می توانید droplets.tf را برای ویرایش باز کنید و خطوط زیر را برای پیاده سازی آن اصلاح کنید:

resource “vpsgol_droplet” “web” {
count = 3
image = “ubuntu-20-04-x64”
name = “test-droplet-${count.index}”
region = “fra1”
size = “s-1vcpu-1gb”
}

output “droplet_ip_addresses” {
value = vpsgol_droplet.web[*].ipv4_address
}

پس از ذخیره فایل ، پروژه را با اجرای دستور زیر اعمال کنید:

terraform apply -var “do_token=${DO_PAT}”

خروجی دریافت خواهید کرد که اکنون یک لیست است و فقط شامل آدرس های IP Droplets است:

Output…
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

droplet_ip_addresses = [
“ip_address”,
“ip_address”,
“ip_address”,
]

برای دریافت خروجی به عنوان JSON ، دستور زیر را اجرا کنید:

terraform output -json droplet_ip_addresses

خروجی یک آرایه واحد خواهد بود:

Output[“ip_address”,”ip_address”,”ip_address”]

شما از خروجی ها همراه با عبارات splat و حلقه ها برای صادر کردن آدرس های IP قطره های مستقر استفاده کرده اید. شما همچنین محتویات خروجی را به عنوان JSON دریافت کرده اید و اکنون از jq – ابزاری برای فیلتر پویا JSON با توجه به عبارات داده شده – برای تجزیه آنها استفاده می کنید.

تجزیه خروجی ها با استفاده از jq

در این مرحله ، شما اصول اولیه jq ، ابزاری برای دستکاری اسناد JSON را نصب و یاد می گیرید. از آن برای تجزیه خروجی های پروژه Terraform خود استفاده خواهید کرد.

اگر از اوبونتو استفاده می کنید ، دستور زیر را برای نصب jq اجرا کنید:

sudo snap install jq

در macOS ، می توانید از Homebrew برای نصب آن استفاده کنید:

brew install jq

jq عبارت پردازش ارائه شده را بر روی ورودی داده شده اعمال می کند ، که می توان آن را وارد کرد. ساده ترین کار در jq این است که ورودی را به خوبی چاپ کنید:

terraform output -json droplet_ip_addresses | jq ‘.’

وارد کردن عملگر هویت (.) بدین معناست که کل سند JSON تجزیه شده از ورودی باید بدون هیچ گونه تغییری خروجی داده شود:

Output[
“first_ip_address”,
“second_ip_address”,
“third_ip_address”
]

شما می توانید فقط IP دوم را با استفاده از نماد براکت آرایه با شمارش صفر درخواست کنید:

terraform output -json droplet_ip_addresses | jq ‘.[1]’

خروجی خواهد بود:

Output”second_ip_address”

برای ایجاد نتیجه پردازش یک آرایه ، عبارت را در داخل پرانتز بپیچید:

terraform output -json droplet_ip_addresses | jq ‘[.[1]]’

شما یک آرایه JSON بسیار چاپ شده دریافت خواهید کرد:

Output[
“second_ip_address”
]

با تعیین طیف وسیعی از نمایه ها در داخل براکت ها می توانید قسمت هایی از آرایه ها را به جای تک عناصر بازیابی کنید:

terraform output -json droplet_ip_addresses | jq ‘.[0:2]’

خروجی خواهد بود:

Output[
“first_ip_address”,
“second_ip_address”
]

محدوده 0: 2 دو عنصر اول را برمی گرداند – قسمت بالای محدوده (2) شامل نمی شود ، بنابراین فقط عناصر در موقعیت های 0 و 1 واکشی می شوند.

اکنون می توانید منابع مستقر شده را با اجرای زیر از بین ببرید:

terraform destroy -var “do_token=${DO_PAT}”

در این مرحله ، jq را نصب کرده اید و از آن برای تجزیه و دستکاری خروجی پروژه Terraform خود ، که سه Droplet را استقرار می دهد ، استفاده کرده اید.

نتیجه

شما با خروجی های Terraform آشنا شده اید ، از آنها برای نشان دادن جزئیات در مورد منابع مستقر و صادرات ساختار داده برای پردازش خارجی بعدی استفاده کرده اید. شما همچنین از خروجی ها برای نشان دادن ویژگی های یک منبع واحد و همچنین برای نشان دادن نقشه های ساخته شده و لیست های حاوی ویژگی های منبع استفاده کرده اید.

Terraformخرید vpsخرید سرورفروش سرورمدیریت داده های زیرساخت

  • behnam gol mohamadi
  • ۰
  • ۰

مشارکت در نرم افزار منبع باز: Kubernetes

ورود به سایت

آیا علاقه دارید با جامعه Kubernetes درگیر شوید ، اما مطمئن نیستید از کجا شروع کنید؟ این پست وبلاگ با هدف کمک به رفع ابهام مربوط به مشارکت در یک پروژه منبع باز به بزرگی Kubernetes و ارائه تجربیات حدیثی به شما این ایده را می دهد که مشارکت در یک پروژه منبع باز مانند Kubernetes می تواند به عنوان یک مبتدی به نظر برسد.

امیدوارم با بیان جزئیات تجربه خود به عنوان مشارکت کننده ، به شما انگیزه دهم تا اولین قدم را برای شروع راه خود به عنوان مشارکت کننده منبع باز بردارید. شما می توانید بدون توجه به سابقه یا سالها تجربه خود در Kubernetes مشارکت داشته باشید. مشارکت همه بخش مهمی و ارزشمند از جامعه منبع باز است. در زیر ، من تجربیات خود را به عنوان مشارکت کننده شرح می دهم و مراحل کلیدی را که هرکسی می تواند برای مشارکت انجام دهد ، شرح می دهد.

چرا من شروع به مشارکت در Kubernetes کردم

مشارکت در یک پروژه منبع باز مانند Kubernetes اشکال مختلفی دارد: ارسال PR های کد ، به روزرسانی اسناد ، مسائل مربوط به تریاژ ، گزارش اشکالات ، بهبود تست ها ، مرور کد ، بررسی پیشنهادات بهبود Kubernetes (KEPs) و مشارکت در مدیریت انتشار Kubernetes . Kubernetes به لطف ساعات بیشماری که توسط همکاران فعلی و مشارکت کنندگان آینده مانند شما سپری شده است ، وجود دارد و رشد می کند.

اولین بار با Kubernetes آشنا شدم که از من خواسته شد یک مطالعه تجاری در مورد راهکارهایی بنویسم که شرکتی که در آن کار می کردم می تواند برای محدود کردن خدمات ما و مدیریت آنها با یک ارکستر کانتینر استفاده کند. با آگاهی از آنچه Kubernetes می تواند انجام دهد ، در شغل بعدی ام زمانی که متوجه ناسازگاری هایی در نحوه نگهداری و عملکرد برخی از برنامه ها شدم ، و استفاده از کانتینریشن را به عنوان یک راه حل پیشنهاد کردم ، در واقع کار خود را آغاز کردم. این به من اجازه داد تا مخزن Kubernetes را کشف کنم ، و در حین انجام این کار با مشکلی روبرو شدم که اولین مشارکت خوب به نظر می رسید.

من همیشه علاقه مند بودم که در پروژه های منبع باز مشارکت کنم و احساس می کردم اگر مشارکت در Kubernetes را شروع کنم ، در مورد سیستم های توزیع شده اطلاعات بیشتری کسب خواهم کرد. هیچ چیز به اندازه نوشتن کد برای آن تجربه ای به شما نمی دهد ، به این ترتیب من درگیر Kubernetes شدم و چرا انجام چنین کاری برای دیگران بسیار ارزشمند است.

نحوه کمک به Kubernetes به عنوان یک مبتدی

در اینجا برخی از اولین قدم هایی است که باید برای شروع مشارکت در Kubernetes انجام دهید.

1. به دنبال مستندات مربوطه باشید که برای مشارکت کنندگان موجود است

به طور معمول ، هنگامی که شما مشارکت کننده جدیدی در هر پروژه منبع باز هستید ، باید به دنبال هرگونه اسناد مرتبط برای مشارکت کنندگان باشید. معمولاً ، این به صورت یک فایل CONTRIBUTING.md یا چیزی مشابه است. README در ریشه یک repo نیز مکان خوبی برای شروع است. هر پروژه ای که به دنبال پرورش جامعه مشارکت کنندگان است باید این اطلاعات را به راحتی در اختیار مشارکت کنندگان جدید قرار دهد. مورد دیگری که باید مورد توجه قرار گیرد ، وسایل ارتباطی است که توسعه دهندگان در آن پروژه یا پروژه فرعی خاص از آن استفاده می کنند. به عنوان مثال ، Kubernetes به شدت به Slack و لیستهای پستی متکی است: مشترک کانالهای Slack و ایمیلهای مورد علاقه خود شوید ، به ویژه برای مناطق Kubernetes که قصد دارید در آنها مشارکت داشته باشید.

به عنوان یک مبتدی کامل برای Kubernetes به طور کلی ، و همچنین فردی که هیچ تجربه ای در مشارکت در پایگاه کد Kubernetes نداشت ، من مستقیماً به فایل CONTRIBUTING.md رفتم. این به خوبی مستند شده است و به من مستندات لازم را برای تنظیم محیط من برای شروع توسعه نشان داد.

2. مسائلی را که به شما علاقه دارند جستجو و فیلتر کنید

  • یافتن مشکلاتی برای کار: هنگامی که محیط برنامه نویس خود را تنظیم کردید ، می خواهید چیزی را پیدا کنید که روی آن کار کنید. هنگامی که من برای اولین بار شروع به کار کردم ، پس از اینکه محیط خود را تنظیم کردم ، به بررسی مسائل موجود در repo Kubernetes پرداختم. در GitHub ، هنگامی که مسائل مربوط به یک پروژه خاص را جستجو می کنید ، یک برچسب فیلترینگ وجود دارد که می تواند برای فیلتر کردن ” is:open is:issue label:”good first issue”” اعمال شود که نشان می دهد این مسئله می تواند توسط یک مبتدی کار شود. به عنوان مثال ، is:open is:issue label:”good first issue” ” در نوار جستجوی شماره GitHub لیستی از همه مسائل باز شده با برچسب “good first issue” را در اختیار شما قرار می دهد. برای فیلتر کردن بیشتر برای یک گروه علاقه مندی خاص (SIG) مانند sig/network ، عبارت “open is: issue”: برچسب ” is:open is:issue label:”good first issue”” را جستجو کنید: sig/network. از اینجا من توانستم اولین شماره خود را پیدا کنم.
  • رفع مشکلاتی که پیدا می کنید: پس از یافتن مشکلی ، باید به نگهبانان اطلاع دهید که قصد شما از کار روی آن چیست. اولین کاری که من انجام دادم این بود که در مورد GitHub بپرسم که آیا می توانم روی موضوعی که پیدا کردم کار کنم ، یعنی PR برای حذف تمام خطوط اضافی اضافی که به توابع Logf () منتقل می شوند. این شامل گذراندن کد در هر دو آزمون/e2e و test/e2e_node ، پیدا کردن مازاد خط جدید در تماس با Logf () و حذف آنها بود. این کار تمرین خوبی برای یادگیری نحوه مشارکت در پایگاه کد Kubernetes بود زیرا شامل تغییرات محلی ، ایجاد روابط عمومی در برابر شاخه اصلی و پرداختن به بازخورد بازبینی می شد.

در طول فرایند ، مهم این بود که در مورد بازخوردی که من متوجه آن نشدم ، توضیحاتی بخواهم. به عنوان مثال ، عبارت “یافتن و رفع مجرمان” گیج کننده بود زیرا نمی دانستم مجرم چیست. اما یک بار که پرسیدم ، یک پاسخ ساده دریافت کردم که به من می گفت که این بدان معناست که تمام خطوط عقب را در سراسر کد e2e حذف کنم.

  • ارتباطات کلیدی است: ارتباط در سراسر فرایند مشارکت بسیار مهم است و برای توسعه منبع باز بسیار مهم است. اگر در روابط عمومی گیر کرده اید ، مطمئن نیستید که چگونه به بازخورد بپردازید یا منطق آن را درک نمی کنید ، سوال بپرسید. بهتر است در مورد مشارکت کننده بیش از حد ارتباط برقرار کنید ، از جمله برقراری ارتباط زمانی که باید از پروژه عقب نشینی کنید. استراحت در توسعه منبع باز انتظار می رود و به حساب می آید و ارتباطات باعث شفافیت و تکرار سریعتر کار انجام شده می شود. با برقراری ارتباط واضح ، اطمینان حاصل می کنید که همه افرادی که در یک پروژه در سراسر جهان کار می کنند مطلع هستند ، در وقت خود صرفه جویی کرده و مواردی را که در ترجمه گم می شوند به حداقل می رسانند.

به عنوان یک مشارکت کننده جدید ، هنگام کار روی اولین کارم احساس عدم اطمینان و سردرگمی کردم. من معتقدم راحت بودن با ندانستن راه حل برای رسیدگی به مسائلی که به شما محول شده و پیش بردن راه حل بسیار ارزشمند است. این بدان معنا نیست که در یک اتاق تاریک بنشینید و خودتان آن را حل کنید ، این بدان معناست که وقتی نیاز به توضیح مشکل دارید ، هنگامی که با اصطلاحات آشنا نیستید ، همانطور که در مثال قبلی اشاره کردم ، یا حتی وقتی که فقط می خواهم به راه حل پیشنهادی خود چشم دوخته باشم این نگرش متکی بر کار گروهی و همکاری در مواقع ضروری به شما کمک می کند تا در مشارکت منبع باز و به طور کلی در فناوری پیشرفت زیادی داشته باشید. به خاطر داشته باشید ، به عنوان محرک راه حلی شما باید مجموعه ای از اشکال زدایی و اطلاعاتی باشید که در تلاش برای حل مشکل در حین همکاری با دیگران به دست آورده اید. به طور معمول هیچ مهلت واقعی (مگر اینکه به طور دیگری اعلام شود) در ارتباط با این “اولین مسائل خوب” وجود ندارد ، بنابراین خیالتان راحت باشد تا زمانی که لازم است از پیشرفت مداوم در موضوع GitHub اطمینان حاصل کنید و افراد را در جریان نگه دارید ، دیگران را درگیر کنید در صورت نیاز کمک کند اگر در نهایت متوجه شدید که دیگر پهنای باندی برای کار روی آن ندارید ، در مورد موضوع مربوطه صحبت کنید و شخص دیگری آن را انتخاب خواهد کرد.

3. در پیدا کردن مسائل گیر کرده اید؟ سعی کنید سایه انتشار repo Kubernetes شوید

راه دیگر برای مشارکت از طریق به روزرسانی اسناد است ، که روشی متداول برای مشارکت کنندگان جدید است تا در یک پروژه منبع باز غیر از تغییرات کد مشارکت کنند. یکی از راههای جالبی که اخیراً در آن شرکت کرده ام ، برنامه سایه انتشار Kubernetes است ، برنامه ای که در آن افراد تازه وارد مدیریت انتشارات Kubernetes می توانند در یکی از بخشهای مختلف نسخه کار کنند. من روی پیشرفتهای Kubernetes 1.20 کار کردم. وظیفه ای که به من محول شد ، بررسی و ردیابی همه پیشنهادات Kubernetes Enhancements (KEPs) ، با کمک چند سایه دیگر و یک سرنخ بود. این به من اطلاعات زیادی در مورد روند KEP داد و به من اجازه داد تا با تعداد کمی از مشارکت کنندگان در این روند کار کنم. من این مسیر را به هر کسی که به دنبال راه اندازی مجدد شبکه و تأثیر خود در جامعه Kubernetes است ، بسیار توصیه می کنم.

مزایای عضویت در Kubernetes

تبدیل شدن به یک عضو Kubernetes نتیجه مشارکت مکرر و همکاری نزدیک با حداقل 2 عضو مختلف مختلف با قابلیت های بازبینی برای یک پروژه خاص در repo Kubernetes است. به عبارت دیگر ، در پروژه Kubernetes به 2 حوزه مختلف کمک زیادی کنید و شخصی را پیدا کنید که بتوانید از نزدیک با هر یک از آنها کار کنید. با گذشت زمان ، هنگامی که تجربه کسب می کنید و برخی روابط عمومی را تحت پوشش خود دارید ، از این افراد بپرسید که آیا می توانند برای عضویت از شما حمایت کنند.

یکی از مزایای اصلی عضویت در این است که بتوانید مسائل مربوط به خود را تعیین کرده و تأثیر بیشتری بر بخش های خاصی از کدی که روی آن کار می کنید داشته باشید. یکی دیگر از مزایای ملموس عضویت ، دریافت آسیب پذیری ها و مواجهه های مشترک Kubernetes (CVE) به محض تشخیص توسط جامعه است. این امر برای تیم vpsgol Kubernetes بسیار ارزشمند بود زیرا ما اطلاعات مربوط به این آسیب پذیری های امنیتی را قبل از عموم مردم دریافت می کنیم و به ما این امکان را می دهد که تلاش های ناخواسته برای به خطر انداختن پلت فرم ما و اطمینان از حفظ امنیت مشتریانمان در حین استفاده از DOKS و سایر محصولات مبتنی بر Kubernetes در بستر vpsgol را خنثی کنیم.

موانع مشترک در راه شما برای تبدیل شدن به یک مشارکت کننده Kubernetes

موانع زیادی وجود دارد که می تواند از پیشرفت در کمک به Kubernetes جلوگیری کند یا سرعت شما را کاهش دهد. مانع اصلی این است که اولین کد خود را وارد کنید. با توجه به تعداد زیاد مشارکت های روزانه و تعداد محدود مرورگران ، برخی از روابط عمومی می توانند ماه ها یا بیشتر بمانند. راه مقابله با این مسئله این است که مطمئن شوید در حال ارسال کدی هستید که در واقع مورد نیاز است. شما می توانید با پیوند دادن آن به یک مسئله موجود یا ایجاد مشکلی برای به دست آوردن اجماع از صاحبان کدی که می خواهید به آن مشارکت کنید ، مشکلی واقعی داشته باشید و تأییدکنندگان/بازبینان آن ناحیه از کد را درگیر کنید. شما قصد مشارکت دارید

1. کمک به کد بدون همکاری با جامعه

به یاد داشته باشید ، تعهدات رانندگی ممکن است به همان سرعتی که انتظار دارید بازبینی نشوند. نگهدارندگان یک پروژه فقط می توانند کارهای زیادی انجام دهند و زمینه های زیادی را در خود نگه دارند. وظیفه شما به عنوان مشارکت کننده است که روابط عمومی خود را تا آنجا که ممکن است بررسی کنید. برای روابط عمومی روابط عمومی خود توضیحات خوب و مکتوب ارائه دهید. اگر این یک تغییر بزرگ است ، مطمئن شوید که در مورد تغییر توافق شده است و در صورت لزوم آن را در روابط عمومی متعدد قرار دهید. در صورت گذشت زمان از زمان ایجاد روابط عمومی و پاسخ به موقع به نظرات در مورد روابط عمومی خود ، با احترام به نگهدارندگان در کانال ضعیف مناسب ضربه بزنید.

2. متواضع نبودن یا احترام به عنوان مشارکت کننده

مانع دیگری که من در مشارکت کنندگان جدید می بینم خودخواهی است. در بسیاری از مواقع ، موضوعی که برای شما جدید است برای دیگران جدید نیست ، بنابراین مهم است که آنها را بشنوید و در گفتمان مدنی پیش بروید. با تصور داشتن تمام اطلاعات لازم برای انجام روابط عمومی ، به هیچ وجه وارد نشوید و به نظرات دیگران گوش دهید و هنگام ارائه/به روز رسانی راه حل خود برای هر موضوعی که روی آن کار می کنید ، آنها را در نظر بگیرید. اگر افراد درخواست به روزرسانی می کنند و شما با آنها موافق نیستید ، در مورد پیشنهادات توضیح دهید تا هر دو از نتیجه راضی باشید. زیبایی منبع باز ، توانایی همکاری با دیگران و ایجاد تکرار در یک محصول است که منجر به خالص مثبت پروژه مورد کار می شود. به یاد داشته باشید که همه ما در یک تیم هستیم و مسائل را شخصی نمی گیریم!

بازبینی: چگونه می توان به عنوان یک مبتدی به عنوان منبع باز Kubernetes تبدیل شد

  1. منطقه ای از K8 ها را پیدا کنید که به شما علاقه دارد و “اولین شماره خوب” را با موضوعات دارای برچسب پیدا کنید تا بلافاصله روی آن کار کنید.
  2. به یاد داشته باشید ، ارتباط زیاد خوب است.
  3. وظیفه را به شیوه ای مثبت دنبال کنید.
  4. در طول مسیر به دیگران کمک کنید ، درست همانطور که در شروع کار می خواهید.

open source, خرید سرور, سرور مجازی, فروش vps, منبع باز

  • behnam gol mohamadi