What is a shell

In Linux, some commands are executed on this command line, which is actually called a shell. Therefore, this shell is actually a bridge for users to communicate with the Linux system. What we want the Linux system to do, we just need to perform corresponding operations through this shell. What does shell programming mean? Shell programming is actually to assemble a single command executed in the shell into a file according to certain logic and rules, which can be directly executed in the later execution. This file is called shell script. So shell programming, in the end, is all about developing a shell script.

The first shell script

The first line of the shell script reads: #! The /bin/bash statement is a package guide that introduces the shell’s execution environment. Note that the # on the first line is not a comment. The # on the other lines is a comment. Let’s create our first shell script by creating a new directory to hold our script

[root@bigdata01 ~]# mkdir shell [root@bigdata01 ~]# cd shell/ [root@bigdata01 shell]# [root@bigdata01 shell]# vi hello.sh #! /bin/bashCopy the code

So now we can write shell commands so let’s do a Hello world and put a comment in there

[root@bigdata01 shell]# vi hello.sh #! /bin/bash # first command echo hello world!Copy the code

Save the file, and your first shell script is developed.

Executing shell scripts

Bash hello.sh bash: is the executable program of the shell, and then specifies the name of the script

[root@bigdata01 shell]# bash hello.sh 
hello world!
Copy the code

Sh: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin: /bin

[root@bigdata01 shell]# ll /bin/bash 
-rwxr-xr-x. 1 root root 964600 Aug 8 2019 /bin/bash
Copy the code

Sh is a link file that also points to the bash file under the /bin directory

[root@bigdata01 shell]# ll /bin/sh 
lrwxrwxrwx. 1 root root 4 Mar 28 20:54 /bin/sh -> bash
Copy the code

Bash and sh used to correspond to two types of shell, but they have since been unified, so we don’t distinguish them here. Therefore, the first line of the shell script is /bin/bash, or /bin/sh, which is the same. Whether to use bash or sh is entirely up to you.

Note that when you look at other data, it is usually said that you need to add the execute permission to the script before it can be executed. Why did we not add the execute permission to the script? You can see here that the script really only has read and write permissions

[root@bigdata01 shell]# ll 
total 4 
-rw-r--r--. 1 root root 45 Apr 2 16:11 hello.sh
Copy the code

The main reason is that if we specify bash or sh, we pass the contents of hello.sh directly to bash or sh, so it doesn’t matter whether the script has permission to execute.

Let’s add execute permission to this script

chmod u+x hello.sh

[root@bigdata01 shell]# chmod u+x hello.sh 
[root@bigdata01 shell]# ll 
total 4 
-rwxr--r--. 1 root root 45 Apr 2 16:11 hello.sh
Copy the code

/hello.sh (); /hello.sh (); /hello.sh (); Indicates the current directory, indicating that the script is executed in the current directory

[root@bigdata01 shell]# ./hello.sh   
hello world!  
Copy the code

The full path specified here can also be executed

[root@bigdata01 shell]# /root/shell/hello.sh 
hello world!
Copy the code

Can we simplify it a little bit and not have any path information in front of it?

[root@bigdata01 shell]# hello.sh 
-bash: hello.sh: command not found
Copy the code

Is the command not found? Confused? You may have seen this in some other materials or videos, but it is also possible to specify the script execution directly. Now we have CD to the directory where the file is located, which should be able to find, so why the prompt can not be found?

Open the /etc/profile file and add export PATH=.:$PATH on the last line. Save the file.

[root@bigdata01 shell]# vi /etc/profile ........ . . export PATH=.:$PATHCopy the code

Then run source /etc/profile to reload the environment variable configuration file, which will take effect immediately, and retry hello.sh. Ok to success

[root@bigdata01 shell]# hello.sh 
hello world!
Copy the code

Finally, I will talk about a small command, the single step execution of shell script, which can facilitate script debugging.

[root@bigdata01 shell]# bash -x hello.sh + echo hello 'world! ' hello world!Copy the code

The content starting with the + sign indicates the command to be executed in the script, and the following content is the result of execution, so that if the script has many commands, it is clearer.

Variables in the shell

Definition of variables in shell

Learning any programming language requires learning variables first, and shell is no exception. However, it should be noted that variables in shell do not need to be declared or initialized. Shell is a weakly typed language, while JAVA is a strongly typed language, and variables need to be declared in advance and variable types specified.

Variable naming requirements in shell: only numbers, letters, and underscores can be used, and cannot start with a number. Variable assignment is performed by “=”. There can be no Spaces between variable, equal sign, and value! -bash: name: command not found -bash: name: command not found -bash: name: command not found

[root@bigdata01 shell]# name=zs 
[root@bigdata01 shell]# name =zs 
-bash: name: command not found 
[root@bigdata01 shell]# name= zs 
-bash: zs: command not found 
[root@bigdata01 shell]# name2_=zs 
[root@bigdata01 shell]# 2name_=zs 
-bash: 2name_=zs: command not found 
[root@bigdata01 shell]# name2$=zs 
-bash: name2$=zs: command not found
Copy the code

Print the value of the variable, using the echo command

[root@bigdata01 shell]# echo $name 
zs
[root@bigdata01 shell]# echo ${name} 
zs
Copy the code

You can write it either way, you can write it the full way, you can write it the reduced way, what’s the difference? If we want to seamlessly concatenate other strings directly after the result of a variable, we can only use the curly bracketed form

[root@bigdata01 shell]# echo $namehehe 
[root@bigdata01 shell]# echo ${name}hehe 
zshehe
Copy the code

It doesn’t matter if it has Spaces

[root@bigdata01 shell]# echo $name hehe 
zs hehe
Copy the code

Classification of variables in the shell

There are four types of variables in the shell

  • The local variable
  • The environment variable
  • Location variables
  • Special variables

The local variable

The format of a local variable is VAR_NAME=VALUE, which is a variable defined directly in the shell. This variable is usually used to define temporary variables in the shell script, which are only valid for the current shell process, and then disappear after the shell process is closed. Invalid for children of the current shell process and for other shell processes. Echo $name: echo $name: echo $name: echo $name: echo $name: echo $name: echo $name: echo $name: echo $name How does this work for children of the current shell process? Run the pstree command to check the current process tree information, but the prompt name cannot be found

[root@bigdata01 shell]# pstree 
-bash: pstree: command not found
Copy the code

Do not worry, do not find this command, just need to install it, here we can use yum fast online installation, then you can specify pstree directly after yum. No, sometimes the name of the command package is different from the name of the actual command. What can be done in this case? Psmisc: yum install PSTree for psMISC: Yum Install PSTree for PSMISC

[root@bigdata01 shell]# yum install -y psmisc 
Copy the code

Perform pstree



Now let’s enter the shell’s child process. How? It’s as simple as just executing bash.

[root@bigdata01 shell]# bash
Copy the code

Then print the value of the name variable

[root@bigdata01 shell]# echo $name
Copy the code

Then run pstree to check whether the current shell process is a child process of the previous shell



Finally, run exit to exit the subshell process.

[root@bigdata01 shell]# exit 
exit
Copy the code

The environment variable

Let’s take a look at the environment variables in the shell. The environment variables here are similar to the environment variables in Windows. For example, if you set the JAVA_HOME environment variable in Windows, the format is: Export VAR_NAME=VALUE the format is to add an export parameter to the local variable format. The format of the environment variable is mainly used to set temporary environment variables. The environment variable disappears when you close the current shell process, and is valid for subshell processes. Invalidation of other shell processes Note that environment variables are not valid for the same scope as local variables and are valid for subshell processes. So let’s do that

[root@bigdata01 shell]# export age=18 
[root@bigdata01 shell]# echo $age 
18
[root@bigdata01 shell]# bash 
[root@bigdata01 shell]# echo $age 
18
Copy the code

Run exit to roll back to the parent shell process

[root@bigdata01 shell]# exit 
exit
Copy the code

Note that in the actual work, we usually set the environment variable to make it permanent. This temporary is not applicable. How to set it to permanent? This temporary setting is added to the specified configuration file, and the command in the specified configuration file will be loaded every time the shell process is started. In this case, it will be added to the /etc/profile file to ensure that it is valid for all users

[root@bigdata01 shell]# vi /etc/profile ........... . . export age=19Copy the code

It turns out that the value of age is 18. It is not 19 as defined in the configuration file, which means that the setting does not take effect. Why? Since the shell process was already started, it loads the commands in /etc/profile by default when started. Now if we want it to reload /etc/profile, we need to run source /etc/profile

[root@bigdata01 shell]# source /etc/profile 
[root@bigdata01 shell]# echo $age 
19
Copy the code

Location variables

$0, $1, $2; $0, $1, $2; $0, $1, $2; The location.sh ABC XYZ location variable is actually equivalent to the args parameter of the Main function in Java. It can be dynamically retrieved from shell scripts so that different business logic can be dynamically executed based on external parameters. You’re going to see a lot of the use of location variables as we go along and we’re going to show you how to create a script file called location.sh and print out these location variables and see what they are

[root@bigdata01 shell]# vi location.sh #! /bin/bash echo $0 echo $1 echo $2 echo $3Copy the code

Run the sh location.sh ABC xyz script

[root@bigdata01 shell]# sh location.sh abc xyz 
location.sh 
abc 
xyz
Copy the code

It turns out that $0 is the name of the script. $1 is the first parameter after the script. $2 is the second parameter after the script. $3 is empty because there are only two parameters after the script. Separate multiple parameters with Spaces.

Special variables

Finally, let's look at special variables in the shell. For special variables, we are going to look at the following two: first, $? It is the return status code of the previous command. If the command is successfully executed, the return status code is 0. If the command fails, the return status code is 1 to 255. Let me show youCopy the code
[root@bigdata01 shell]# ll 
total 8 
-rwxr--r--. 1 root root 45 Apr 2 16:11 hello.sh 
-rw-r--r--. 1 root root 44 Apr 3 16:23 location.sh 
[root@bigdata01 shell]# echo $?
0 
[root@bigdata01 shell]# lk 
-bash: lk: command not found [root@bigdata01 shell]#
echo $? 
127
Copy the code
Status Code Description 0 Command ended successfully 1 General Unknown Error 127 Command not found 128 Invalid Exit parameter 128+x Critical error of Linux signal X 130 Command Ctrl+C control code out of bounds 255 Exit code out of boundsCopy the code

The second special variable is $#, which represents the number of arguments to the shell script. For example, create paramnum.sh

[root@bigdata01 shell]# vi paramnum.sh #! /bin/bash echo $#Copy the code

Then perform

[root@bigdata01 shell]# sh paramnum.sh a b c 
3 
[root@bigdata01 shell]# sh paramnum.sh a b c d 
4
Copy the code

This special variable application scenario, suppose our script at run time need three parameters was obtained from the dynamic outside, so need to assess the first script before executing scripts behind any designated three parameters, if 1 specifies the parameter, that this script is not necessary to carry out direct stop, number of parameters is not enough, Execution is meaningless.

Special use of variables and quotes

Previously we looked at variables in the shell, but there are some special scenarios for variables and quotes to work with. Let’s take a look at the first one: single quotes do not parse variables

[root@bigdata01 shell]# name=jack 
[root@bigdata01 shell]# echo '$name' 
$name
Copy the code

Then look at the double quotes, “” : double quotes parse variables

[root@bigdata01 shell]# name=jack 
[root@bigdata01 shell]# echo "$name" 
jack
Copy the code

There is also a special quote, which we call the back quote, in the upper left corner of the keyboard under ESC, which can be typed in English input mode

[root@bigdata01 shell]# name=jack 
[root@bigdata01 shell]# echo `$name` 
-bash: jack: command not found
Copy the code

Backquotes are the result of executing and quoting the command. In this case, backquotes are the result of getting the value of the name variable, and then executing it, and then not finding the command. If we change the value of name to PWD and see what happens, then PWD will be executed and the result of PWD will be printed.

[root@bigdata01 shell]# name=pwd 
[root@bigdata01 shell]# echo `$name` 
/root/shell
Copy the code

There is another way to use the backquotes, $(). They work the same way, depending on which one you prefer.

And one last tip is to notice that sometimes we want to put quotes around the value of a variable, how do we do that? Echo “$name” does not work; the final value is unquoted

[root@bigdata01 shell]# echo "$name" 
pwd
Copy the code

What if I put a single quote around it? The variable is not parsed, although the value is enclosed in double quotes

[root@bigdata01 shell]# echo '"$name"' 
"$name"
Copy the code

What else is there to do? Take a look at this operation, put a single quotation mark, then a double quotation mark, and that’s it.

[root@bigdata01 shell]# echo "'$name'" 
'pwd'
Copy the code

Related syntax in shell

The for loop

The for loop format is similar to the Java for loop format, but not the same

for((i=0; i<10; I++)) do loop body... doneCopy the code

To demonstrate this, create for1.sh first

[root@bigdata01 shell]# vi for1.sh #! /bin/bash for((i=0; i<10; i++)) do echo $i doneCopy the code

Notice, the do here could also be on the same line as the for, just with a semicolon;

[root@bigdata01 shell]# vi for1.sh #! /bin/bash for((i=0; i<10; i++)); do echo $i doneCopy the code

Execute see result

[root@bigdata01 shell]# sh for1.sh 01 2......Copy the code

This format is suitable for iterating multiple times with the same step size. Next, the second format is convenient for iterating over random lists or a limited number of lists

For I in 1 2 3 do... doneCopy the code

Just to show you,

[root@bigdata01 shell]# vi for2.sh #! /bin/bash for i in 1 2 3 do echo $i doneCopy the code

Execute and see the result

[root@bigdata01 shell]# sh for2.sh 
1 
2 
3
Copy the code

This is how the shell uses the for loop

The while loop

The while loop is mainly used when the number of loops is unknown, or it is not convenient to use for to generate a large list directly. The format of the while loop is:

While testing conditional do loop body... doneCopy the code

Notice the test condition here, if it’s true, it’s in the loop, if it’s false, it’s out of the loop so how do we define that test condition? It supports test EXPR or [EXPR], the second form of which contains a space between parentheses and expressions. The comparison logic in shell is a little different. Take a look at the integer test: -gt(greater than), -lt(less than), -ge(greater than or equal to), -le(less than or equal to), -eq(equal to), -ne(not equal to) Use the = sign, the = sign here is not the meaning of assignment, does not equal to use! String test: =(equal to),! Create while1.sh. Note that we need to use sleep to implement the hibernation operation, otherwise the program will continue

[root@bigdata01 shell]# vi while1.sh #! /bin/bash while test 2 -gt 1 do echo yes sleep 1 doneCopy the code

Execute the script and press CTRL + C to exit the program forcibly

[root@bigdata01 shell]# sh while1.sh 
yes 
yes 
yes ...
Copy the code

Modify the test condition and execute it without printing anything because the test condition is false

[root@bigdata01 shell]# vi while1.sh #! /bin/bash while test 2 -lt 1 do echo yes sleep 1 done [root@bigdata01 shell]# sh while1.shCopy the code

I don’t really like the format of the test condition, I like to use brackets, it’s a little bit more clear but you have to make sure there’s a space between the brackets and the expression inside, otherwise you’ll get an error

[root@bigdata01 shell]# cp while1.sh while2.sh [root@bigdata01 shell]# vi while2.sh #! /bin/bash while [ 2 -gt 1 ] do echo yes sleep 1 done [root@bigdata01 shell]# sh while2.sh yes yes yes ...Copy the code

Finally, try a test for strings

[root@bigdata01 shell]# cp while2.sh while3.sh [root@bigdata01 shell]# vi while3.sh #! /bin/bash while [ "abc" = "abc" ] do echo yes sleep 1 done [root@bigdata01 shell]# sh while3.sh yes yes yes ...Copy the code

If judgment

If judgments come in three forms

  • Single branch
  • Double branch
  • Many branches

Let’s take a look at the single branch, which looks like this

If test condition then select branch FICopy the code

This also uses test conditions, so to demonstrate this, create if1.sh as in while where we can dynamically take an argument and judge it dynamically within the test condition

[root@bigdata01 shell]# vi if1.sh #! /bin/bash flag=$1 if [ $flag -eq 1 ] then echo one fiCopy the code

Execute the script

[root@bigdata01 shell]# sh if1.sh 1 
one 
[root@bigdata01 shell]# sh if1.sh 
if1.sh: line 3: [: -eq: unary operator expected
Copy the code

Behind here found that if the script doesn’t pass parameters, execute a program error, error message seems not elegant, it shows that our program is not strong, so can be optimized To judge the script first behind the number of parameters, if the parameter number is not enough, directly out of line, use the exit can exit the program here, And we can return a status code at the end of the program. If the program does not pass any arguments, it will execute exit 100 to terminate the program and return a status code of 100. Let’s verify that

[root@bigdata01 shell]# vi if1.sh 
#! /bin/bash 
if [ $# -lt 1 ] 
then 
	echo "not found param" 
	exit 100 
fi 
flag=$1 
if [ $flag -eq 1 ] 
then
	echo "one" 
fi 
[root@bigdata01 shell]# sh if1.sh 
not found param 
[root@bigdata01 shell]# echo $?
100
Copy the code

For this script, the normal execution logic would be that if the parameters passed do not match, there would be no output and this would not be very friendly. Would it be possible to prompt the user when the wrong data is executed? Of course you can, so you need to use the double branch of if as follows:

If test condition then select branch 1 else select branch 2 FICopy the code

Copy a script and modify it

[root@bigdata01 shell]# cp if1.sh if2.sh [root@bigdata01 shell]# vi if2.sh #! /bin/bash if [ $# -lt 1 ] then echo "not found param" exit 100 fi flag=$1 if [ $flag -eq 1 ] then echo "one" else echo "not support" fiCopy the code

Execute the script

[root@bigdata01 shell]# sh if2.sh 1 
one 
[root@bigdata01 shell]# sh if2.sh 2 
not support
Copy the code

Currently, only numbers 1 are supported. What if you want to support more numbers? We need to use the multi-branch condition of if in the following format:

If test condition 1 then select branch 1 elif test condition 2 then select branch 2 Else Select branch N FICopy the code

Copy a script and modify it

[root@bigdata01 shell]# cp if2.sh if3.sh 
[root@bigdata01 shell]# vi if3.sh
#! /bin/bashif [ $# -lt 1 ] exit 100 fi flag=$1 if [ $flag -eq 1 ] then echo "one" elif [ $flag -eq 2 ] then echo "two" elif [ $flag  -eq 3 ] then echo "three" else echo "not support" fiCopy the code

Execute the script

[root@bigdata01 shell]# sh if3.sh 1 
one 
[root@bigdata01 shell]# sh if3.sh 2 
two 
[root@bigdata01 shell]# sh if3.sh 3 
three 
[root@bigdata01 shell]# sh if3.sh 4 
not support
Copy the code

The shell extension

Background running of shell script: Encountered this kind of situation, in the practical work with the while infinite loop shell script, we hope that it will have been running, does not affect me in this window to perform other operations But now and it will take up the shell window, we call this script is now at the front desk, don’t want it to have been occupied shell window, You need to put it in the background, how do you put it in the background? Very simple, add an & at the end of the script to demonstrate, and that’s it

[root@bigdata01 shell]# sh while2.sh & 
[1]2228
Copy the code

However, when we close the window, we find that the shell script that we put in the background has also stopped running. We want this script to continue running in the background

[root@bigdata01 ~]# ps -ef|grep while2 
root 2325 2306 0 20:48 pts/2 00:00:00 grep --color=auto while2
Copy the code

How can I ensure that closing a shell window does not affect the execution of shell scripts placed in the background? By default, when we close the shell window, the shell window will send a stop signal to all shell scripts that it started. When we add nohup, the stop signal will be blocked. So shell scripts that are already in the background won’t stop. demonstrate

[root@bigdata01 shell]# nohup sh while2.sh & [1]2326 Nohup: Ignoring input and appending output to 'nohup.out'Copy the code

Note: After nohup is used, the output of the script is stored in a nohup.out log file in the current directory by default. This log file can be used to check the execution of the script later. The only way to stop the shell script is to use kill

[root@bigdata01 shell]# ps -ef|grep while2 
root 2326 2306 0 20:51 pts/2 00:00:00 sh while2.sh 
root 3515 2306 0 21:11 pts/2 00:00:00 grep --color=auto while2 
[root@bigdata01 shell]# kill 2326 
[root@bigdata01 shell]# ps -ef|grep while2 
root 3525 2306 0 21:11 pts/2 00:00:00 grep --color=auto while2
Copy the code

Standard output: indicates a normal message output by a command or program. Standard error output: indicates an error message output by a command or program

[root@bigdata01 shell]# ll 
total 52 
-rw-r--r--. 1 root root 48 Apr 3 17:32 for1.sh 
-rw-r--r--. 1 root root 43 Apr 3 17:40 for2.sh 
[root@bigdata01 shell]# lk 
-bash: lk: command not found
Copy the code

Ll perform successful here, so the output information is the standard output Lk here is not a command, execution fails, the output information is below the standard error output standard output can be using the file descriptor is 1, the standard error output can use the file descriptor 2 to said According to the standard output and standard error, You can use a redirection operation to save the output to a file

[root@bigdata01 shell]# ll 1> a.txt [root@bigdata01 shell]# more a.txt total 52 -rw-r--r--. 1 root root 0 Apr 3 21:39 a.txt -rw-r--r--. 1 root root 48 Apr 3 17:32 for1.sh -rw-r--r--. 1 root root 43 Apr 3 17:40 for2.sh -rwxr--r--. 1 root root 45 Apr 2 16:11 hello.sh -rw-r--r--. 1 root root 121 Apr 3 18:30 if1.sh -rw-r--r--. 1 root root 147 Apr 3 18:30 if2.sh -rw-r--r--. 1 root root 227 Apr 3 18:34 if3.sh -rw-r--r--. 1 root root 44 Apr 3 16:23 location.sh -rw-------. 1 root root 4692 Apr 3 21:11 nohup.out -rw-r--r--. 1 root root 20 Apr 3 16:48 paramnum.sh -rw-r--r--. 1 root root 56 Apr 3  17:59 while1.sh -rw-r--r--. 1 root root 55 Apr 3 18:01 while2.sh -rw-r--r--. 1 root root 61 Apr 3 18:03 while3.shCopy the code

Repeating this command will see no change in the contents of the file because > overwrites the previous contents

[root@bigdata01 shell]# ll 1> a.txt [root@bigdata01 shell]# more a.txt total 52 -rw-r--r--. 1 root root 0 Apr 3 21:39 a.txt -rw-r--r--. 1 root root 48 Apr 3 17:32 for1.sh -rw-r--r--. 1 root root 43 Apr 3 17:40 for2.sh -rwxr--r--. 1 root root 45 Apr 2 16:11 hello.sh -rw-r--r--. 1 root root 121 Apr 3 18:30 if1.sh -rw-r--r--. 1 root root 147 Apr 3 18:30 if2.sh -rw-r--r--. 1 root root 227 Apr 3 18:34 if3.sh -rw-r--r--. 1 root root 44 Apr 3 16:23 location.sh -rw-------. 1 root root 4692 Apr 3 21:11 nohup.out -rw-r--r--. 1 root root 20 Apr 3 16:48 paramnum.sh -rw-r--r--. 1 root root 56 Apr 3  17:59 while1.sh -rw-r--r--. 1 root root 55 Apr 3 18:01 while2.sh -rw-r--r--. 1 root root 61 Apr 3 18:03 while3.shCopy the code

If you want to append, you need to use >>

[root@bigdata01 shell]# ll 1>> a.txt
Copy the code

Note that the 1 can be omitted because it is also a 1 by default. Standard error output is used in the same way as this, standard error output requires a 2, and you can’t redirect this error output to a file with a 1.

[root@bigdata01 shell]# lk 1> b.txt 
-bash: lk: command not found
Copy the code

The correct way to write it is this.

[root@bigdata01 shell]# lk 2> b.txt 
[root@bigdata01 shell]# more b.txt 
-bash: lk: command not found
Copy the code

Nohup hello.sh >/dev/null 2>&1 &

/dev/null: redirects the standard output to the black hole, indicating that the output of the script does not need to be stored. 2>&1: Redirects the standard error output to the standard outputCopy the code

The timer crontab

Check the crontab service status: systemCtrl Status crond Start /stop the crontab service: systemCtrl start/stop crond Add a scheduled task: vi /etc/crontab

Suppose we have a requirement to print the current time every minute in the format of year, month, day, hour, minute, second

[root@bigdata01 shell]# vi showTime.sh #! /bin/bash showTime=`date "+%Y-%m-%d %H:%M:%S"` echo $showTimeCopy the code

Then configure it in the /etc/crontab file



Every 1 minute, which is actually the simplest way to write it, you just have to start with asterisks, so it matches

And that’s the end result

* * * * * root sh /root/shell/showTime.sh

After this validation scripts can be normal execution can save the configuration file, but there is a problem Now this kind of situation after the script execution results we are not saved, if let crontab timing schedule execution, we simply can’t see the results of the information, so we need to debug the results of the script to a file, Run the append redirection command * * * * * root sh /root/shell/showtime. sh >> /root/shell/showtime. log to save the configuration file and wait for execution. Let’s take a look at the resulting file and verify that it is executing properly, using tail -f to monitor it for a while

[root@bigdata01 shell]# tail -f /root/shell/showTime.log 2026-04-06 21:14:01 2026-04-06 21:15:01 2026-04-06 21:16:01 .Copy the code

If we execute a script that does not produce any output, how do we verify that the script is successfully scheduled? In this case, you can check crontab logs in the /var/log/cron file and run the tail -f command to monitor crontab logs in real time

[root@bigdata01 shell]# tail -f /var/log/cron 
......... 
Apr 6 21:14:01 bigdata01 CROND[1577]: (root) CMD (sh /root/shell/showTime.sh 
Apr 6   21:15:01 bigdata01 CROND[1584]: (root) CMD (sh /root/shell/showTime.sh 
Apr 6 21:16:01 bigdata01 CROND[1591]: (root) CMD (sh /root/shell/showTime.sh 
Apr 6 21:17:01 bigdata01 CROND[1597]: (root) CMD (sh /root/shell/showTime.sh 
Apr 6 21:18:01 bigdata01 CROND[1603]: (root) CMD (sh /root/shell/showTime.sh
Copy the code