Bash betikleri: başlangıç

Bash betikleri: başlangıç
Bash Komut Dosyaları Bölüm 2: Döngüler
Bash Komut Dosyaları, Bölüm 3: Komut Satırı Seçenekleri ve Seçenekleri
Bash Komut Dosyaları Bölüm 4: Giriş ve Çıkış
Bash Komut Dosyaları, Bölüm 5: Sinyaller, Arka Plan Görevleri, Komut Dosyası Yönetimi
Bash Komut Dosyaları, Bölüm 6: İşlevler ve Kitaplık Geliştirme
Bash Komut Dosyaları, Bölüm 7: sed ve Kelime İşleme
Bash betikleri, bölüm 8: awk veri işleme dili
Bash Komut Dosyaları Bölüm 9: Normal İfadeler
Bash Scriptleri Bölüm 10: Pratik Örnekler
Bash betikleri, bölüm 11: etkileşimli yardımcı programların beklenmesi ve otomasyonu

Bugün bash betiklerinden bahsedeceğiz. Bu - komut satırı komut dosyaları, bash kabuğu için yazılmıştır. Zsh, tcsh, ksh gibi başka kabuklar da var ama biz bash'a odaklanacağız. Bu materyal herkese yöneliktir, tek koşul çalışma yeteneğidir. Komut satırı Linux.

Bash betikleri: başlangıç

Komut satırı komut dosyaları, klavyeden girilebilen, dosyalar halinde toplanan ve ortak bir amaç doğrultusunda birleştirilen aynı komutların koleksiyonlarıdır. Bu durumda ekiplerin çalışmalarının sonuçları bağımsız bir değere sahip olabilir veya diğer ekipler için girdi verileri olarak hizmet edebilir. Komut dosyaları, sık gerçekleştirilen eylemleri otomatikleştirmenin güçlü bir yoludur.

Bash betikleri: başlangıç

Yani, komut satırından bahsedersek, noktalı virgülle ayırarak birkaç komutu aynı anda çalıştırmanıza olanak tanır:

pwd ; whoami

Aslında bunu terminalinizde denediyseniz, iki komut içeren ilk bash betiğiniz zaten yazılmıştır. Bu şekilde çalışıyor. Önce takım pwd geçerli çalışma dizini hakkındaki bilgileri ve ardından komutu görüntüler whoamiolarak oturum açtığınız kullanıcı hakkındaki bilgileri gösterir.

Bu yaklaşımı kullanarak, istediğiniz kadar komutu tek bir satırda birleştirebilirsiniz; tek sınır, programa aktarılabilecek maksimum argüman sayısıdır. Bu sınırı aşağıdaki komutu kullanarak tanımlayabilirsiniz:

getconf ARG_MAX

Komut satırı harika bir araçtır, ancak her ihtiyaç duyduğunuzda komutları ona girmeniz gerekir. Peki ya bir dosyaya bir takım komutlar yazıp bunları yürütmek için o dosyayı çağırsak? Aslında bahsettiğimiz dosyaya komut satırı betiği denir.

Bash betikleri nasıl çalışır?

Komutu kullanarak boş bir dosya oluşturun touch. İlk satırında hangi kabuğu kullanacağımızı belirtmemiz gerekiyor. İlgileniyoruz bashyani dosyanın ilk satırı şöyle olacaktır:

#!/bin/bash

Bu dosyadaki diğer satırlar, kabuğun işlemediği yorumları belirtmek için karma sembolünü kullanır. Bununla birlikte, ilk satır özel bir durumdur; bir karma ve ardından bir ünlem işareti gelir (bu diziye olay) ve ona giden yol bash, sisteme betiğin özel olarak oluşturulduğunu belirtin bash.

Kabuk komutları satır beslemesiyle, yorumlar ise karma işaretiyle ayrılır. Şuna benziyor:

#!/bin/bash
# This is a comment
pwd
whoami

Burada, tıpkı komut satırında olduğu gibi, komutları noktalı virgülle ayırarak tek satıra yazabilirsiniz. Ancak komutları farklı satırlara yazarsanız dosyanın okunması daha kolay olur. Her durumda kabuk bunları işleyecektir.

Betik dosyası izinlerini ayarlama

Dosyaya bir ad vererek kaydedin myscriptve bash betiğini oluşturma işi neredeyse bitti. Şimdi geriye kalan tek şey bu dosyayı çalıştırılabilir hale getirmektir, aksi takdirde çalıştırmayı denerseniz bir hatayla karşılaşırsınız Permission denied.

Bash betikleri: başlangıç
Yanlış yapılandırılmış izinlerle bir komut dosyasını çalıştırmayı denemek

Dosyayı çalıştırılabilir hale getirelim:

chmod +x ./myscript

Şimdi onu çalıştırmayı deneyelim:

./myscript

İzinleri ayarladıktan sonra her şey olması gerektiği gibi çalışır.

Bash betikleri: başlangıç
Bash betiğini başarıyla çalıştırma

Mesaj çıkışı

Linux konsoluna metin çıktısı vermek için şu komutu kullanın: echo. Bu gerçeğin bilgisinden yararlanalım ve komut dosyamızı düzenleyerek, zaten içinde bulunan komutların verdiği verilere açıklamalar ekleyelim:

#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoami

Güncellenen betiği çalıştırdıktan sonra olan budur.

Bash betikleri: başlangıç
Bir komut dosyasından mesajların çıktısını alma

Artık şu komutu kullanarak açıklayıcı notları görüntüleyebiliriz echo. Linux araçlarını kullanarak bir dosyayı nasıl düzenleyeceğinizi bilmiyorsanız veya komutu daha önce görmediyseniz echo, şuna baksana bu şeyler.

Değişkenleri Kullanma

Değişkenler, diğer komutlar tarafından kullanılmak üzere, komutların sonuçları gibi bilgileri bir komut dosyasında saklamanıza olanak tanır.

Bireysel komutların sonuçlarını saklamadan yürütülmesinde yanlış bir şey yoktur, ancak bu yaklaşımın yetenekleri çok sınırlıdır.

Bash betiklerinde kullanılabilecek iki tür değişken vardır:

  • Ortam Değişkenleri
  • Kullanıcı Değişkenleri

Ortam Değişkenleri

Bazen kabuk komutlarının bazı sistem verileriyle çalışması gerekir. Geçerli kullanıcının ana dizininin nasıl görüntüleneceğine dair bir örnek:

#!/bin/bash
# display user home
echo "Home for the current user is: $HOME"

Lütfen bir sistem değişkeni kullanabileceğimizi unutmayın. $HOME çift ​​tırnak içinde bu, sistemin onu tanımasını engellemez. Yukarıdaki senaryoyu çalıştırırsanız elde edeceğiniz şey budur.

Bash betikleri: başlangıç
Bir komut dosyasında ortam değişkeni kullanma

Ekranda dolar işareti göstermeniz gerekirse ne olur? Hadi bunu deneyelim:

echo "I have $1 in my pocket"

Sistem, alıntılanan bir dizede bir dolar işareti algılayacak ve bir değişkene referans verdiğimizi varsayacaktır. Betik tanımlanmamış bir değişkenin değerini görüntülemeye çalışacaktır $1. İhtiyacımız olan şey bu değil. Ne yapalım?

Bu durumda, dolar işaretinden önce bir ters eğik çizgi olan kaçış karakterini kullanmak yardımcı olacaktır:

echo "I have $1 in my pocket"

Betik artık tam olarak bekleneni verecektir.

Bash betikleri: başlangıç
Dolar işareti yazdırmak için kaçış dizisini kullanma

Kullanıcı Değişkenleri

Ortam değişkenlerine ek olarak bash komut dosyaları, komut dosyasında kendi değişkenlerinizi tanımlamanıza ve kullanmanıza olanak tanır. Bu tür değişkenler, komut dosyası yürütmeyi tamamlayana kadar bir değer tutar.

Sistem değişkenlerinde olduğu gibi kullanıcı değişkenlerine de dolar işareti kullanılarak erişilebilir:
TNW-CUS-FMP - hizmetlerimizde %10 indirim için promosyon kodu, 7 gün içinde etkinleştirilebilir

#!/bin/bash
# testing variables
grade=5
person="Adam"
echo "$person is a good boy, he is in grade $grade"

Böyle bir betiği çalıştırdıktan sonra olan budur.

Bash betikleri: başlangıç
Komut Dosyasındaki Özel Değişkenler

Komut Değiştirme

Bash betiklerinin en kullanışlı özelliklerinden biri, komut çıktısından bilgi çıkarma ve onu değişkenlere atama yeteneğidir; bu, bu bilgiyi betik dosyasının herhangi bir yerinde kullanmanıza olanak tanır.

Bu iki şekilde yapılabilir.

  • "`" geri işaretini kullanma
  • Tasarım gereği $()

İlk yaklaşımı kullanırken, geri tıklama yerine tek bir tırnak işareti kullanmamaya dikkat edin. Komut bu tür iki simgenin içine alınmalıdır:

mydir=`pwd`

İkinci yaklaşımda aynı şey şu şekilde yazılmıştır:

mydir=$(pwd)

Ve senaryo şu şekilde görünebilir:

#!/bin/bash
mydir=$(pwd)
echo $mydir

Çalışması sırasında komutun çıktısı pwdbir değişkene kaydedilecek mydir, içeriği, komutu kullanarak echo, konsola gidecek.

Bash betikleri: başlangıç
Bir komutun sonuçlarını bir değişkene kaydeden bir komut dosyası

Matematiksel işlemler

Bir komut dosyasında matematiksel işlemler gerçekleştirmek için aşağıdaki gibi bir yapı kullanabilirsiniz: $((a+b)):

#!/bin/bash
var1=$(( 5 + 5 ))
echo $var1
var2=$(( $var1 * 2 ))
echo $var2

Bash betikleri: başlangıç
Bir Komut Dosyasında Matematiksel İşlemler

if-then kontrol yapısı

Bazı senaryolarda komut yürütme akışını kontrol etmeniz gerekir. Örneğin, belirli bir değer beşten büyükse bir eylem gerçekleştirmeniz gerekir, aksi takdirde başka bir eylem gerçekleştirmeniz gerekir. Bu birçok durumda uygulanabilir ve burada kontrol yapısı bize yardımcı olacaktır. if-then. En basit haliyle şöyle görünür:

if команда
then
команды
fi

İşte çalışan bir örnek:

#!/bin/bash
if pwd
then
echo "It works"
fi

Bu durumda komut yürütülürse pwdbaşarıyla tamamlandığında konsolda "çalışıyor" yazısı görüntülenecektir.

Sahip olduğumuz bilgiyi kullanalım ve daha karmaşık bir senaryo yazalım. Diyelim ki belirli bir kullanıcıyı bulmamız gerekiyor /etc/passwdve bulmayı başardıysanız var olduğunu bildirin.

#!/bin/bash
user=likegeeks
if grep $user /etc/passwd
then
echo "The user $user Exists"
fi

Bu betiği çalıştırdıktan sonra olan budur.

Bash betikleri: başlangıç
Kullanıcı arama

Burada şu komutu kullandık grepbir dosyada kullanıcı aramak için /etc/passwd. Eğer takım grepsize tanıdık gelmiyor, açıklamasını bulabilirsiniz burada.

Bu örnekte, eğer kullanıcı bulunursa, komut dosyası buna karşılık gelen bir mesaj görüntüleyecektir. Kullanıcı bulunamazsa ne olur? Bu durumda, betik bize hiçbir şey söylemeden yürütmeyi tamamlayacaktır. Bize bunu da anlatmasını istiyoruz, böylece kodu geliştireceğiz.

if-then-else kontrol yapısı

Programın hem başarılı bir aramanın hem de başarısızlığın sonuçlarını raporlayabilmesi için inşaatı kullanacağız. if-then-else. İşte nasıl çalışıyor:

if команда
then
команды
else
команды
fi

İlk komut sıfır döndürürse, bu başarıyla yürütüldüğü anlamına gelir, koşul doğru olacak ve yürütme dal boyunca ilerlemeyecektir. else. Aksi takdirde, sıfırdan farklı bir değer döndürülürse, bu başarısızlık veya yanlış sonucu gösterir. else.

Aşağıdaki betiği yazalım:

#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
else
echo "The user $user doesn’t exist"
fi

Onun infazı boşa gitti else.

Bash betikleri: başlangıç
Bir betiği if-then-else yapısıyla çalıştırma

Peki, devam edelim ve kendimize daha karmaşık koşullar hakkında soralım. Peki ya bir durumu değil birden fazlasını kontrol etmeniz gerekiyorsa? Örneğin, istenen kullanıcı bulunursa bir mesaj görüntülenmeli, başka bir koşul karşılanırsa başka bir mesaj görüntülenmeli vb. Böyle bir durumda iç içe geçmiş koşullar bize yardımcı olacaktır. Şuna benziyor:

if команда1
then
команды
elif команда2
then
команды
fi

İlk komut, başarılı bir şekilde yürütüldüğünü gösteren sıfır değerini döndürürse, ilk bloktaki komutlar yürütülecektir. thenaksi halde, eğer ilk koşul yanlışsa ve ikinci komut sıfır döndürüyorsa, ikinci kod bloğu yürütülecektir.

#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
elif ls /home
then
echo "The user doesn’t exist but anyway there is a directory under /home"
fi

Böyle bir komut dosyasında örneğin şu komutu kullanarak yeni bir kullanıcı oluşturabilirsiniz: useradd, eğer arama sonuç vermediyse veya başka yararlı bir şey yaptıysa.

Sayıların karşılaştırılması

Komut dosyalarında sayısal değerleri karşılaştırabilirsiniz. Aşağıda ilgili komutların bir listesi bulunmaktadır.

n1 -eq n2Eğer doğruysa döner n1 olduğu n2.
n1 -ge n2 Eğer doğruysa döner n1daha fazla veya eşit n2.
n1 -gt n2Eğer doğruysa döner n1 daha fazla n2.
n1 -le n2Eğer doğruysa döner n1daha az veya eşit n2.
n1 -lt n2n1'in değeri şu değerden küçükse true değerini döndürür: n2.
n1 -ne n2Eğer doğruysa döner n1eşit değil n2.

Örnek olarak karşılaştırma operatörlerinden birini deneyelim. İfadenin köşeli parantez içine alındığına dikkat edin.

#!/bin/bash
val1=6
if [ $val1 -gt 5 ]
then
echo "The test value $val1 is greater than 5"
else
echo "The test value $val1 is not greater than 5"
fi

Bu komutun çıktısı budur.

Bash betikleri: başlangıç
Kodlardaki sayıların karşılaştırılması

Değişken değer val15'ten büyükse dal yürütülür thenkarşılaştırma operatörü ve karşılık gelen mesaj konsolda görüntülenir.

Dize karşılaştırması

Komut dosyaları ayrıca dize değerlerini de karşılaştırabilir. Karşılaştırma operatörleri oldukça basit görünse de string karşılaştırma işlemlerinin aşağıda değineceğimiz belirli özellikleri vardır. İşte operatörlerin listesi.

str1 = str2 Dizelerin eşitliğini test eder, dizeler aynıysa true değerini döndürür.
str1 != str2Dizeler aynı değilse true değerini döndürür.
str1 < str2Eğer doğruysa döner str1daha az str2.
str1 > str2 Eğer doğruysa döner str1fazla str2.
-n str1 Uzunluk varsa true değerini döndürür str1Sıfırın üstünde.
-z str1Uzunluk varsa true değerini döndürür str1sıfıra eşittir.

Bir komut dosyasındaki dizeleri karşılaştırmanın bir örneğini burada bulabilirsiniz:

#!/bin/bash
user ="likegeeks"
if [$user = $USER]
then
echo "The user $user  is the current logged in user"
fi

Komut dosyasının yürütülmesi sonucunda aşağıdakileri elde ederiz.

Bash betikleri: başlangıç
Komut dosyalarındaki dizeleri karşılaştırma

Burada dize karşılaştırmasının bahsetmeye değer bir özelliği var. Yani, ">" ve "<" operatörlerinin önüne ters eğik çizgi konulmalıdır, aksi halde hiçbir hata mesajı görünmese de komut dosyası düzgün çalışmayacaktır. Betik ">" işaretini çıktı yönlendirme komutu olarak yorumlar.

Bu operatörlerle çalışmanın kodda nasıl göründüğü aşağıda açıklanmıştır:

#!/bin/bash
val1=text
val2="another text"
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

İşte betiğin sonuçları.

Bash betikleri: başlangıç
Dize karşılaştırması, uyarı verildi

Lütfen komut dosyasının çalıştırılmasına rağmen bir uyarı verdiğini unutmayın:

./myscript: line 5: [: too many arguments

Bu uyarıdan kurtulmak için şu sonuca varıyoruz: $val2 çift ​​tırnak içinde:

#!/bin/bash
val1=text
val2="another text"
if [ $val1 > "$val2" ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

Artık her şey olması gerektiği gibi çalışıyor.

Bash betikleri: başlangıç
Dize karşılaştırması

">" ve "<" operatörlerinin bir diğer özelliği de büyük ve küçük harflerle nasıl çalıştıklarıdır. Bu özelliği anlayabilmek için aşağıdaki içeriğe sahip bir metin dosyası hazırlayalım:

Likegeeks
likegeeks

Bir isim vererek kaydedelim myfileardından terminalde aşağıdaki komutu çalıştırın:

sort myfile

Dosyadaki satırları şu şekilde sıralayacaktır:

likegeeks
Likegeeks

Ekip sort, varsayılan olarak dizeleri artan düzende sıralar; yani örneğimizdeki küçük harf, büyük harften küçüktür. Şimdi aynı stringleri karşılaştıracak bir script hazırlayalım:

#!/bin/bash
val1=Likegeeks
val2=likegeeks
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

Çalıştırırsanız, her şeyin tam tersi olduğu ortaya çıkıyor - küçük harf artık büyük harften daha büyük.

Bash betikleri: başlangıç
Sıralama komutu ve bir komut dosyasındaki dizeleri karşılaştırma

Karşılaştırma komutlarında büyük harfler küçük harflerden daha küçüktür. Buradaki dize karşılaştırması, karakterlerin ASCII kodlarının karşılaştırılması yoluyla yapılır; sıralama düzeni dolayısıyla karakter kodlarına bağlıdır.

Ekip sort, sistem dili ayarlarında belirtilen sıralama düzenini kullanır.

Dosya kontrolleri

Belki de aşağıdaki komutlar bash betiklerinde en sık kullanılır. Dosyalarla ilgili çeşitli koşulları kontrol etmenize olanak tanırlar. İşte bu komutların bir listesi.

-d fileBir dosyanın var olup olmadığını ve bir dizin olup olmadığını kontrol eder.
-e fileDosyanın var olup olmadığını kontrol eder.
-f file Bir dosyanın var olup olmadığını ve bir dosya olup olmadığını kontrol eder.
-r fileDosyanın var olup olmadığını ve okunabilir olup olmadığını kontrol eder.
-s file ПDosyanın var olup olmadığını ve boş olup olmadığını kontrol eder.
-w fileDosyanın var olup olmadığını ve yazılabilir olup olmadığını kontrol eder.
-x fileDosyanın var olup olmadığını ve yürütülebilir olup olmadığını kontrol eder.
file1 -nt file2 Daha yeni olup olmadığını kontrol eder file1göre file2.
file1 -ot file2Daha eski olup olmadığını kontrol eder file1göre file2.
-O file Dosyanın mevcut olup olmadığını ve geçerli kullanıcıya ait olup olmadığını kontrol eder.
-G fileDosyanın mevcut olup olmadığını ve grup kimliğinin geçerli kullanıcının grup kimliğiyle eşleşip eşleşmediğini kontrol eder.

Bu komutların yanı sıra bugün tartışılan diğer birçok komutun hatırlanması kolaydır. Çeşitli kelimelerin kısaltması olan isimleri doğrudan yaptıkları kontrolleri belirtmektedir.

Komutlardan birini pratikte deneyelim:

#!/bin/bash
mydir=/home/likegeeks
if [ -d $mydir ]
then
echo "The $mydir directory exists"
cd $ mydir
ls
else
echo "The $mydir directory does not exist"
fi

Bu komut dosyası, mevcut bir dizin için içeriğini gösterecektir.

Bash betikleri: başlangıç
Bir dizinin içeriğini listeleme

Geri kalan komutları kendi başınıza deneyebileceğinize inanıyoruz; hepsi aynı prensibe göre kullanılıyor.

sonuçlar

Bugün bash betikleri yazmaya nasıl başlayacağımızdan bahsettik ve bazı temel konuları ele aldık. Aslında bash programlamanın konusu çok büyük. Bu makale, 11 materyalden oluşan geniş bir serinin ilk bölümünün çevirisidir. Hemen devam etmek isterseniz işte bu malzemelerin orijinallerinin listesi. Kolaylık olması açısından az önce okuduğunuz metnin çevirisi buraya eklenmiştir.

  1. Bash Komut Dosyası Adım Adım - burada bash betikleri oluşturmaya nasıl başlayacağımızdan bahsediyoruz, değişkenlerin kullanımı dikkate alınıyor, koşullu yapılar, hesaplamalar, sayıların, dizelerin karşılaştırmaları ve dosyalar hakkında bilgi bulma anlatılıyor.
  2. Bash Komut Dosyası Oluşturma Bölüm 2, Muhteşem Bash — burada for ve while döngüleriyle çalışmanın özellikleri ortaya çıkıyor.
  3. Bash Komut Dosyası Oluşturma Bölüm 3, Parametreler ve seçenekler — bu materyal, kullanıcının girdiği ve dosyalardan okunabilen verilerle çalışan, komut dosyalarına aktarılabilen komut satırı parametrelerine ve anahtarlara ayrılmıştır.
  4. Bash Komut Dosyası Oluşturma Bölüm 4, Giriş ve Çıkış - burada dosya tanımlayıcılardan ve onlarla çalışmaktan, giriş, çıkış, hata akışları ve çıkış yönlendirmesinden bahsediyoruz.
  5. Bash Komut Dosyası Oluşturma Bölüm 5, Sighals ve İşler — bu materyal Linux sinyallerine, bunların komut dosyalarında işlenmesine ve komut dosyalarının bir programa göre başlatılmasına ayrılmıştır.
  6. Bash Komut Dosyası Oluşturma Bölüm 6, İşlevler — burada komut dosyalarında işlevler oluşturma ve kullanma ve kitaplıklar geliştirme hakkında bilgi edinebilirsiniz.
  7. Bash Komut Dosyası Oluşturma Bölüm 7, sed Kullanımı — bu makale sed akışlı metin düzenleyiciyle çalışmaya ayrılmıştır.
  8. Bash Komut Dosyası Oluşturma Bölüm 8, awk Kullanımı — bu materyal awk veri işleme dilinde programlamaya ayrılmıştır.
  9. Bash Komut Dosyası Oluşturma Bölüm 9, Düzenli İfadeler — burada bash betiklerinde normal ifadelerin kullanımı hakkında bilgi edinebilirsiniz.
  10. Bash Komut Dosyası Oluşturma Bölüm 10, Pratik Örnekler — burada kullanıcılara gönderilebilecek mesajlarla çalışma tekniklerinin yanı sıra disk izleme yöntemini de bulabilirsiniz.
  11. Bash Komut Dosyası Oluşturma Bölüm 11, Komut Bekle — bu materyal, etkileşimli yardımcı programlarla etkileşimi otomatikleştirebileceğiniz Expect aracına ayrılmıştır. Özellikle, beklenen betiklerden ve bunların bash betikleri ve diğer programlarla etkileşiminden bahsediyoruz.

Bu makale serisinin değerli özelliklerinden birinin, her düzeydeki kullanıcıya uygun olan en basitinden başlayarak, yavaş yavaş oldukça ciddi konulara yol açması ve herkese Linux komut satırı komut dosyalarının oluşturulmasında ilerleme şansı vermesi olduğuna inanıyoruz. .

Sevgili okuyucular! Bash programlama gurularından ustalıklarının doruğuna nasıl ulaştıklarını konuşmalarını, sırlarını paylaşmalarını istiyoruz ve ilk senaryolarını yeni yazanların izlenimlerini almayı sabırsızlıkla bekliyoruz.

Bash betikleri: başlangıç

Ankete sadece kayıtlı kullanıcılar katılabilir. Giriş yapLütfen.

Makale serisinin geri kalanını çevirmeli miyim?

  • Evet!

  • Hayır gerek yok

1030 kullanıcı oy kullandı. 106 kişi çekimser kaldı.

Kaynak: habr.com

Yorum ekle