Как да работим с променливи в Bash

Променливите са жизненоважни, ако искате да пишете скриптове и да разберете какво ще направи този код, който ще изрежете и поставите от мрежата на вашия Linux компютър. Ние ще ви помогнем да започнете!

Променливи 101

Променливите са наименувани символи, които представляват низ или числова стойност. Когато ги използвате в команди и изрази, те се третират така, сякаш сте въвели стойността, която те съдържат, вместо името на променливата.

За да създадете променлива, трябва само да предоставите име и стойност за нея. Имената на променливите ви трябва да са описателни и да ви напомнят за стойността, която притежават. Името на променлива не може да започва с число, нито може да съдържа интервали. Може обаче да започне с долна черта. Освен това можете да използвате всяка комбинация от главни и малки букви и цифри.

Примери

Тук ще създадем пет променливи. Форматът е да въведете името, знака за равенство = и стойността. Обърнете внимание, че няма интервал преди или след знака за равенство. Даването на стойност на променлива често се нарича присвояване на стойност на променливата.

Ще създадем четири низови променливи и една числова променлива, this_year:

me=Dave
my_boost=Linux
him=Popeye
his_boost=Spinach
this_year=2019

Да се виж стойността задържан в променлива, използвайте командата echo. Трябва да предхождате името на променливата със знак за долар $, когато се позовавате на стойността, която съдържа, както е показано по-долу:

echo $my_name
echo $my_boost
echo $this_year

В

Нека използваме всички наши променливи наведнъж:

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

В

Стойностите на променливите заместват имената им. Можете също да промените стойностите на променливите. За да присвоите нова стойност на променливата my_boost, просто повтаряте това, което сте направили, когато сте присвоили първата й стойност, така:

my_boost=Tequila

В

Ако изпълните отново предишната команда, сега получавате различен резултат:

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

Ехото

Така че можете да използвате същата команда, която препраща към едни и същи променливи и да получите различни резултати, ако промените стойностите, съхранявани в променливите.

Ще говорим за цитирането на променливи по-късно. Засега ето някои неща, които трябва да запомните:

Променлива в единични кавички ‘ се третира като литерален низ, а не като променлива.
Променливите в кавички ” се третират като променливи.
За да получите стойността, съхранявана в променлива, трябва да предоставите знака за долар $.
Променлива без знака за долар $ предоставя само името на променливата.

Можете също да създадете променлива, която взема стойността си от съществуваща променлива или брой променливи. Следната команда дефинира нова променлива, наречена drink_of_the_Year, и й присвоява комбинираните стойности на променливите my_boost и this_year:

drink_of-the_Year="$my_boost $this_year"
echo drink_of_the-Year

Напитката_на_годината=

Как да използвате променливи в скриптове

Скриптовете биха били напълно затруднени без променливи. Променливите осигуряват гъвкавостта, която прави скрипта общо, а не конкретно решение. За да илюстрирате разликата, ето скрипт, който брои файловете в директорията /dev.

  Как да поправите Slow Touch ID на вашия iPhone

Въведете това в текстов файл и след това го запазете като fcnt.sh (за „брой файлове“):

#!/bin/bash

folder_to_count=/dev

file_count=$(ls $folder_to_count | wc -l)

echo $file_count files in $folder_to_count

Преди да можете да стартирате скрипта, трябва да го направите изпълним, както е показано по-долу:

chmod +x fcnt.sh

Въведете следното, за да стартирате скрипта:

./fcnt.sh

Това отпечатва броя на файловете в директорията /dev. Ето как работи:

Дефинирана е променлива, наречена folder_to_count и е настроена да държи низа „/dev.“
Дефинирана е друга променлива, наречена file_count. Тази променлива взема стойността си от заместване на команда. Това е командната фраза между скобите $( ). Обърнете внимание, че преди първата скоба има знак за долар $. Тази конструкция $( ) оценява командите в скобите и след това връща крайната им стойност. В този пример тази стойност се присвоява на променливата file_count. Що се отнася до променливата file_count, тя е предадена стойност, която трябва да се задържи; не се интересува от това как е получена стойността.
Командата, оценена при заместването на командата, изпълнява списък на ls файл в директорията в променливата folder_to_count, която е зададена на „/dev. И така, скриптът изпълнява командата „ls /dev.“
Резултатът от тази команда се предава в командата wc. Опцията -l (брой редове) кара wc да пребройте броя на редовете в изхода от командата ls. Тъй като всеки файл е посочен на отделен ред, това е броят на файловете и поддиректориите в директорията “/dev”. Тази стойност се присвоява на променливата file_count.
Последният ред използва ехо за извеждане на резултата.

Но това работи само за директорията “/dev”. Как можем да накараме скрипта да работи с всяка директория? Всичко, което е необходимо е една малка промяна.

Как да използвате параметрите на командния ред в скриптове

Много команди, като ls и wc, приемат параметри на командния ред. Те предоставят информация на командата, така че тя да знае какво искате да направи. Ако искате ls да работи върху вашата домашна директория и също за показване на скрити файлове, можете да използвате следната команда, където тилдата ~ и опцията -a (всички) са параметри на командния ред:

ls ~ -a

Нашите скриптове могат да приемат параметри на командния ред. Те са посочени като $1 за първия параметър, $2 като втория и така нататък, до $9 за деветия параметър. (Всъщност има и $0, но това е запазено, за да държи скрипта винаги.)

Можете да препращате към параметрите на командния ред в скрипт точно както бихте направили обикновените променливи. Нека да модифицираме нашия скрипт, както е показано по-долу, и да го запишем с новото име fcnt2.sh:

#!/bin/bash

folder_to_count=$1

file_count=$(ls $folder_to_count | wc -l)

echo $file_count files in $folder_to_count

Този път на променливата folder_to_count се присвоява стойността на първия параметър на командния ред, $1.

  Колко голям е твърде голям за документ на Microsoft Word?

Останалата част от скрипта работи точно както преди. Вместо конкретно решение, вашият скрипт вече е общ. Можете да го използвате във всяка директория, защото не е твърдо кодиран да работи само с „/dev.

Ето как можете да направите скрипта изпълним:

chmod +x fcnt2.sh

Сега опитайте с няколко директории. Можете да направите първо „/dev“, за да сте сигурни, че получавате същия резултат като преди. Въведете следното:

./fnct2.sh /dev
./fnct2.sh /etc
./fnct2.sh /bin

Получавате същия резултат (207 файла) както преди за директорията “/dev”. Това е обнадеждаващо и получавате специфични за директорията резултати за всеки от другите параметри на командния ред.

За да съкратите скрипта, можете да се откажете от променливата, folder_to_count, като цяло и просто да препратите $1 навсякъде, както следва:

#!/bin/bash 

file_count=$(ls $1  wc -l) 

echo $file_count files in $1

Работа със специални променливи

Споменахме $0, който винаги е зададен на името на файла на скрипта. Това ви позволява да използвате скрипта, за да правите неща като да отпечатате правилно името му, дори ако е преименуван. Това е полезно в ситуации на регистриране, в които искате да знаете името на процеса, който е добавил запис.

Следват другите специални предварително зададени променливи:

$#: Колко параметра на командния ред са предадени на скрипта.
[email protected]: Всички параметри на командния ред, предадени на скрипта.
$?: Изходното състояние на последния процес за изпълнение.
$$: ID на процеса (PID) на текущия скрипт.
$USER: Потребителското име на потребителя, изпълняващ скрипта.
$HOSTNAME: Името на хоста на компютъра, изпълняващ скрипта.
$SECONDS: Броят секунди, за които скриптът се изпълнява.
$RANDOM: Връща произволно число.
$LINENO: Връща номера на текущия ред на скрипта.

Искате да ги видите всички в един сценарий, нали? Можеш! Запазете следното като текстов файл, наречен special.sh:

#!/bin/bash

echo "There were $# command line parameters"
echo "They are: [email protected]"
echo "Parameter 1 is: $1"
echo "The script is called: $0"
# any old process so that we can report on the exit status
pwd
echo "pwd returned $?"
echo "This script has Process ID $$"
echo "The script was started by $USER"
echo "It is running on $HOSTNAME"
sleep 3
echo "It has been running for $SECONDS seconds"
echo "Random number: $RANDOM"
echo "This is line number $LINENO of the script"

Въведете следното, за да го направите изпълним:

chmod +x special.sh

Сега можете да го стартирате с куп различни параметри на командния ред, както е показано по-долу.

Променливи на средата

Bash използва променливи на средата, за да дефинира и записва свойствата на средата, която създава, когато се стартира. Тази задържана информация, до която Bash има лесен достъп, като вашето потребителско име, локал, броят на командите, които вашият файл с история може да задържи, вашият редактор по подразбиране и много други.

За да видите активните променливи на средата във вашата Bash сесия, използвайте тази команда:

env | less

В

Ако превъртите списъка, може да намерите някои, които биха били полезни за препратка във вашите скриптове.

Как да експортирате променливи

Когато скриптът се изпълнява, той е в собствен процес и променливите, които използва, не могат да се видят извън този процес. Ако искате да споделите променлива с друг скрипт, който вашият скрипт стартира, трябва да експортирате тази променлива. Ще ви покажем как да направите това с два скрипта.

  Какво е Inbox Zero и как можете да го постигнете?

Първо запазете следното с името на файла script_one.sh:

#!/bin/bash

first_var=alpha
second_var=bravo

# check their values
echo "$0: first_var=$first_var, second_var=$second_var"

export first_var
export second_var

./script_two.sh

# check their values again
echo "$0: first_var=$first_var, second_var=$second_var"

Това създава две променливи, first_var и second_var, и присвоява някои стойности. Той ги отпечатва в прозореца на терминала, експортира променливите и извиква script_two.sh. Когато script_two.sh приключи и потокът на процеса се върне към този скрипт, той отново отпечатва променливите в прозореца на терминала. След това можете да видите дали са се променили.

Вторият скрипт, който ще използваме, е script_two.sh. Това е скриптът, който script_one.sh извиква. Въведете следното:

#!/bin/bash

# check their values
echo "$0: first_var=$first_var, second_var=$second_var"

# set new values
first_var=charlie
second_var=delta

# check their values again
echo "$0: first_var=$first_var, second_var=$second_var"

Този втори скрипт отпечатва стойностите на двете променливи, присвоява им нови стойности и след това ги отпечатва отново.

За да стартирате тези скриптове, трябва да въведете следното, за да ги направите изпълними:

chmod +x script_one.sh
chmod +x script_two.sh

И сега въведете следното, за да стартирате script_one.sh:

./script_one.sh

Това ни казва изходът:

script_one.sh отпечатва стойностите на променливите, които са алфа и браво.
script_two.sh отпечатва стойностите на променливите (алфа и браво), както ги е получил.
script_two.sh ги променя на charlie и delta.
script_one.sh отпечатва стойностите на променливите, които все още са алфа и браво.

Това, което се случва във втория скрипт, остава във втория скрипт. Сякаш копия на променливите се изпращат към втория скрипт, но те се изхвърлят, когато този скрипт излезе. Оригиналните променливи в първия скрипт не се променят от нищо, което се случва с техните копия във втория.

Как да цитирам променливи

Може би сте забелязали, че когато скриптовете се позовават на променливи, те са в кавички “. Това позволява на променливите да се препращат правилно, така че техните стойности се използват, когато редът се изпълнява в скрипта.

Ако стойността, която присвоявате на променлива, включва интервали, те трябва да са в кавички, когато ги присвоите на променливата. Това е така, защото по подразбиране Bash използва интервал като разделител.

Ето един пример:

site_name=How-To Geek

Bash вижда пространството преди „Geek“ като индикация, че стартира нова команда. То съобщава, че няма такава команда и напуска линията. echo ни показва, че променливата site_name не съдържа нищо — дори текста „How-To“.

Опитайте отново с кавички около стойността, както е показано по-долу:

site_name="How-To Geek"

име_на сайт=

Този път се разпознава като единична стойност и се присвоява правилно на променливата site_name.

echo е вашият приятел

Може да отнеме известно време, за да свикнете със заместване на команди, цитиране на променливи и запомняне кога да включите знака за долар.

Преди да натиснете Enter и да изпълните ред от Bash команди, опитайте го с ехо пред него. По този начин можете да сте сигурни, че това, което ще се случи, е това, което искате. Можете също така да уловите всички грешки, които може да сте направили в синтаксиса.