Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand Linux Shell script programming

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "how to understand Linux Shell script programming". Many people will encounter such a dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Usually, when people mention the "shell scripting language," they think of bash,ksh,sh or other similar linux/unix scripting language. Scripting languages are another way to communicate with computers. Using a graphical window interface (whether it's windows or linux), users can move the mouse and click on a variety of objects, such as buttons, lists, checkboxes, and so on. But this method is very inconvenient every time the user wants the computer / server to complete the same task (such as converting photos in batches, or downloading new movies, mp3, etc.). To make all of these things simple and automated, we can use shell scripts.

Some programming languages, such as pascal, foxpro, C, java, etc., need to be compiled before execution. They need the right compiler to get our code to do something.

Other programming languages, such as php, javascript, visualbasic, etc., do not need a compiler, so they need an interpreter, and we do not need to compile code to run the program.

The shell script is also like an interpreter, but it is usually used to call externally compiled programs. It then captures the output, exits the code, and processes it as appropriate.

One of the most popular shell scripting languages in the Linux world is bash. The reason I think (in my own opinion) is that by default bash shell makes it easy for users to navigate through history commands (previously executed), whereas ksh requires some adjustments to .profile, or remember some "magic" key combinations to view history and correct commands.

Well, I think these introductions are enough. I'll leave it to you to judge which environment is best for you. From now on, I will only talk about bash and its scripts. In the following example, I will use CentOS 6.6 and bash-4.1.2. Please make sure you have the same version, or higher.

Shell script flow

The shell scripting language is similar to chatting with several people. You just need to think of all the commands as people who can do things for you, as long as you ask them to do it in the right way. For example, you want to write a document. First of all, you need paper. Then, you need to tell someone the content and ask him to write it for you. Finally, you want to store it somewhere. In other words, you want to build a house, so you need to hire the right person to clear the site. When they say "it's done", then some other engineers can help you build the wall. Finally, when these engineers tell you "it's done", you can call a painter to paint the house. What happens if you ask the painter to whitewash the wall before it is finished? I think they'll start to complain. Almost all of these human-like commands can talk, and if they get the job done without a problem, they tell "standard output". If they can't do what you tell them to do-they will tell "standard error". In this way, in the end, all commands listen to you through "standard input".

Quick example-when you open the linux terminal and write some text-you are talking to bash through "standard input". So, let's ask bash shell who am i (who am I? ).

The code is as follows:

Root@localhost ~] # who am i out.txt 2 > err.txt

To shorten the statement a little bit, we can ignore "1" because stdout is redirected by default:

Command > out.txt 2 > err.txt well, let's try to do some "bad things". Let's delete file1 and folder1 with the rm command:

The code is as follows:

[root@localhost ~] # rm-vf folder1 file1 > out.txt 2 > err.txt

Now check the following output file:

The code is as follows:

[root@localhost ~] # cat out.txt

Removed `file1'

[root@localhost ~] # cat err.txt

Rm: cannot remove `folder1': Is a directory

[root@localhost ~] #

As we can see, different streams are separated into different files. Sometimes this is not very convenient because we want to see what happens successively before or after certain actions when an error occurs. To do this, we can redirect two streams to the same file:

Command > > out_err.txt 2 > > out_err.txt

Note: please note that I used ">" instead of ">". It allows us to attach to a file instead of overwriting it.

We can also redirect one flow to another:

Command > out_err.txt 2 > & 1

Let me explain. The standard output of all commands will be redirected to out_err.txt, the error output will be redirected to stream 1 (explained above), and the stream will be redirected to the same file. Let's look at this example:

The code is as follows:

[root@localhost] # rm-fv folder2 file2 > out_err.txt 2 > & 1

[root@localhost ~] # cat out_err.txt

Rm: cannot remove `folder2': Is a directory

Removed `file2'

[root@localhost ~] #

Looking at the output of these combinations, we can describe it as follows: first, the rm command tries to delete the folder2, but it will not succeed because linux requires the-r key to allow the rm command to delete the folder, and the second file2 will be deleted. By providing rm with the-v (details) key, we have the rm command tell us each file or folder that has been deleted.

That's almost everything you need to know about redirection. I mean, almost, because there is a more important redirection tool, which is called "pipeline". By using the | (pipe) symbol, we usually redirect the stdout stream.

For example, we have a text file like this:

The code is as follows:

[root@localhost ~] # cat text_file.txt

This line does not contain H e l l o word

This lilne contains Hello

This also containd Hello

This one no due to HELLO all capital

Hello bash world!

We need to find some of these lines with "Hello", and there is a grep command in Linux to do this:

The code is as follows:

[root@localhost ~] # grep Hello text_file.txt

This lilne contains Hello

This also containd Hello

Hello bash world!

[root@localhost ~] #

It works well when we have a file that we want to search in. What if we need to find something in the output of another command? Yes, of course, we can redirect the output to the file, and then look in the file:

The code is as follows:

[root@localhost ~] # fdisk-l > fdisk.out

[root@localhost ~] # grep "Disk / dev" fdisk.out

Disk / dev/sda: 8589 MB, 8589934592 bytes

Disk / dev/mapper/VolGroup-lv_root: 7205 MB, 7205814272 bytes

Disk / dev/mapper/VolGroup-lv_swap: 855 MB, 855638016 bytes

[root@localhost ~] #

What if you plan to grep some double quotation marks to enclose content with spaces!

Note: the fdisk command displays information about disk drives of the Linux operating system.

As we can see, this approach is very inconvenient because we soon messed up the temporary file space. To accomplish this task, we can use pipes. They allow us to redirect the stdout of one command to the stdin stream of another command:

The code is as follows:

[root@localhost ~] # fdisk-l | grep "Disk / dev"

Disk / dev/sda: 8589 MB, 8589934592 bytes

Disk / dev/mapper/VolGroup-lv_root: 7205 MB, 7205814272 bytes

Disk / dev/mapper/VolGroup-lv_swap: 855 MB, 855638016 bytes

[root@localhost ~] #

As you can see, we don't need any temporary files to get the same results. We redirected fdisk stdout to grep stdin.

Note: pipe redirection is always from left to right.

There are several other redirects, but we'll talk about them later.

Display custom information in shell

As we know, usually, communication with shell and communication within shell is carried out in the form of dialogue. So let's create some real scripts that will talk to us, too. This will allow you to learn some simple commands and have a better understanding of the concept of scripts.

Suppose we are the general help desk manager of a company and we want to create some shell script to register the call information: the phone number, the user name, and a brief description of the problem. We intend to store this information in a plain text file data.txt for future statistics. The script itself works in dialogue, which makes life easier for the staff at the front desk. So, first of all, we need to show the questions. For displaying information, we can use the echo and printf commands. Both are used to display information, but printf is more powerful because we can format the output well, we can align it to the right, to the left, or to make room for the information. Let's start with a simple example. To create a file, use your usual text editor (kate,nano,vi,... And then create a file called note.sh with these commands written in it

Echo "Phone number?" How do I run / execute scripts?

After saving the file, we can use the bash command to run it, taking our file as its parameter:

The code is as follows:

[root@localhost ~] # bash note.sh

Phone number?

In fact, it is very inconvenient to execute scripts in this way. It would be more comfortable to execute without using the bash command as a prefix. To make the script executable, we can use the chmod command:

The code is as follows:

[root@localhost ~] # ls-la note.sh

-rw-r--r--. 1 root root 22 Apr 23 20:52 note.sh

[root@localhost ~] # chmod + x note.sh

[root@localhost ~] # ls-la note.sh

-rwxr-xr-x. 1 root root 22 Apr 23 20:52 note.sh

[root@localhost ~] #

Note: the ls command displays the files in the current folder. By adding the-la key, it displays more file information.

As we can see, the script only has read (r) and write (w) permissions before the chmod command is executed. After executing chmod + x, it gets the execute (x) permission. (I will cover more details about permissions in the next article. Now, all we need to do is run like this:

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number?

I added a. / combination before the script name. . (dot) means the current location (current folder) in the unix world, and / (slash) is the folder delimiter. (in Windows systems, we use a backslash\ to indicate the same function.) so the whole combination means: "execute the note.sh script from the current folder." I think you'll know better if I run this script with the full path:

The code is as follows:

[root@localhost ~] # / root/note.sh

Phone number?

[root@localhost ~] #

It works, too.

If all linux users have the same default shell, then everything OK. If we just execute the script, the default user shell will be used to parse the contents of the script and run the command. The syntax, internal commands, and so on of different shell are slightly different, so to ensure that our script uses bash, we should add #! / bin/bash to the first line of the file. In this way, the default user shell will call / bin/bash, and only then will the commands in the script be executed:

The code is as follows:

[root@localhost ~] # cat note.sh

#! / bin/bash

Echo "Phone number?"

Until now, we are 100% sure that bash will be used to parse the contents of our scripts. Let's move on.

Read input

After the information is displayed, the script waits for the user to reply. There is a read command to receive the user's answer:

The code is as follows:

#! / bin/bash

Echo "Phone number?"

Read phone

After execution, the script waits for user input until the user presses the [ENTER] key to end the input:

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number?

12345 > data.txt

[root@localhost ~] #. / note.sh

Phone number?

nine hundred and eighty seven

Name?

Jimmy

Issue?

Keybord issue.

[root@localhost ~] # cat data.txt

987/Jimmy/Keybord issue.

[root@localhost ~] #

Note: the tail command shows the last n lines of the file.

Got it. Let's run it again and see:

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number?

five hundred and fifty six

Name?

Janine

Issue?

Mouse was broken.

[root@localhost ~] # cat data.txt

987/Jimmy/Keybord issue.

556/Janine/Mouse was broken.

[root@localhost ~] #

Our files are growing, so let's add a date to each line, which will be useful for manipulating these statistics in the future. To do this, we can use the date command and specify a format, because I don't like the default format:

The code is as follows:

[root@localhost ~] # date

Thu Apr 23 21:33:14 EEST 2015 data.txt

[root@localhost ~] #. / note.sh

Phone number?

one hundred and twenty three

Name?

Jim

Issue?

Script hanging.

[root@localhost ~] # cat data.txt

2015.04.23 21:38:56/123/Jim/Script hanging.

[root@localhost ~] #

Um... Our script looks a little ugly. Let's beautify it. If you want to read the read command manually, you will find that the read command can also display some information. To do this, we should use the-p key plus information:

The code is as follows:

[root@localhost ~] # cat note.sh

#! / bin/bash

Now= `date "+% Y.%m.%d% H:%M:%S" `

Read-p "Phone number:" phone

Read-p "Name:" name

Read-p "Issue:" issue

Echo "$now/$phone/$name/$issue" > > data.txt

You can find a lot of interesting information about each command directly from the console, just enter: man read, man echo, man date, man...

Do you agree? It looks much more comfortable!

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number: 321

Name: Susane

Issue: Mouse was stolen

[root@localhost ~] # cat data.txt

2015.04.23 21:38:56/123/Jim/Script hanging.

2015.04.23 21:43:50/321/Susane/Mouse was stolen

[root@localhost ~] #

It's interesting that the cursor is behind the message (not on the new line). (LCTT translation note: if the output is displayed with the echo command, you can use the-n argument to avoid line breaks. )

Cycle

It's time to improve our script. If the user has been answering the phone all day, wouldn't it be troublesome to run it every time? Let's let these activities cycle endlessly:

The code is as follows:

[root@localhost ~] # cat note.sh

#! / bin/bash

While true

Do

Read-p "Phone number:" phone

Now= `date "+% Y.%m.%d% H:%M:%S" `

Read-p "Name:" name

Read-p "Issue:" issue

Echo "$now/$phone/$name/$issue" > > data.txt

Done

I have swapped the positions of the read phone and now=date lines. This is because I want to get time after entering the phone number. If I put it on the first line of the loop, the variable now will get time as soon as the data is stored in the file after the loop. This is not good, because the next call may be 20 minutes later, or even later.

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number: 123

Name: Jim

Issue: Script still not works.

Phone number: 777

Name: Daniel

Issue: I broke my monitor

Phone number: ^ C

[root@localhost ~] # cat data.txt

2015.04.23 21:38:56/123/Jim/Script hanging.

2015.04.23 21:43:50/321/Susane/Mouse was stolen

2015.04.23 21:47:55/123/Jim/Script still not works.

2015.04.23 21:48:16/777/Daniel/I broke my monitor

[root@localhost ~] #

Note: to exit from an infinite loop, you can press [Ctrl] + [C] key. Shell displays ^ for the CTRL key.

Use pipe redirection

Let's add more features to our "Frankenstein", and I want the script to display some statistics after each call. For example, I want to check the various numbers and call me several times. For this, we should cat the file data.txt:

The code is as follows:

[root@localhost ~] # cat data.txt

2015.04.23 21:38:56/123/Jim/Script hanging.

2015.04.23 21:43:50/321/Susane/Mouse was stolen

2015.04.23 21:47:55/123/Jim/Script still not works.

2015.04.23 21:48:16/777/Daniel/I broke my monitor

2015.04.23 22:02:14/123/Jimmy/Newscript also not working!!!

[root@localhost ~] #

Now, we can redirect all the output to the cut command, let cut cut each line into pieces (we use the delimiter "/"), and then print the second field:

The code is as follows:

[root@localhost ~] # cat data.txt | cut-d "/"-f2

one hundred and twenty three

three hundred and twenty one

one hundred and twenty three

seven hundred and seventy seven

one hundred and twenty three

[root@localhost ~] #

Now, we can redirect this output to another command, sort:

The code is as follows:

[root@localhost ~] # cat data.txt | cut-d "/"-f2 | sort

one hundred and twenty three

one hundred and twenty three

one hundred and twenty three

three hundred and twenty one

seven hundred and seventy seven

[root@localhost ~] #

And leave only the only line. To count unique entries, simply add the-c key to the uniq command:

The code is as follows:

[root@localhost ~] # cat data.txt | cut-d "/"-f2 | sort | uniq-c

3 123

1 321

1 777

[root@localhost ~] #

Just add this to the end of our loop:

The code is as follows:

#! / bin/bash

While true

Do

Read-p "Phone number:" phone

Now= `date "+% Y.%m.%d% H:%M:%S" `

Read-p "Name:" name

Read-p "Issue:" issue

Echo "$now/$phone/$name/$issue" > > data.txt

Echo "= We got calls from ="

Cat data.txt | cut-d "/"-f2 | sort | uniq-c

Echo "-"

Done

Run:

The code is as follows:

[root@localhost ~] #. / note.sh

Phone number: 454

Name: Malini

Issue: Windows license expired.

= We got calls from =

3 123

1 321

1 454

1 777

-

Phone number: ^ C

The current scene runs through several well-known steps:

● display message

● gets user input

● stores values to files

● processes stored data

But if the user is a little responsible, sometimes he needs to enter data, sometimes he needs statistics, or maybe he needs to look up something in the stored data? For these things, we need to use switches/cases and know how to format the output well. This is useful when "drawing" tables in shell.

This is the end of "how to understand Linux Shell scripting". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report