如何c语言怎么调用函数数 从入门到精通?

函数是被设计为执行特定任务的代码块, 会在某代码调用它时被执行。声明格式function 函数名(parms1, params2, ..., paramsX){
  
//函数体代码
  return 返回值
}
注意事项函数名必须要符合 驼峰式 命名(首字母小写,之后每个单词首字母大写);函数名后面的()中, 可以有参数, 也可以没有参数, 分别称为 有参函数 和 无参函数;声明函数时的参数列表, 称为形参列表, 形式参数(变量的名字), function sayHello (x, y){}, 调用函数时的参数列表称为实参列表, 实际参数(变量的赋值), sayHello(1, 2);函数的形参列表个数, 与实参列表个数没有实际关联关系, 函数参数的个数, 取决于实参列表, 如果实参列表的个数比形参列表少, 则为赋值的形参, 值将为 undefined;函数可以有返回值, 使用 return 返回结果。调用函数时, 可以使用一个变量接受函数的返回结果, 如果函数没有返回值, 则接受的结果为 undefined;函数参数可以设置默认值, 当为 null/undefined 时调用默认值, function sayHello (x, y = 2){}, sayHello(1);函数中变量的作用域, 在函数中, 使用 var 声明的变量, 为局部变量, 只能在函数内部访问, 不使用 var 声明的变量, 为全局变量, 在函数外也能访问;函数的声明与函数的调用没有先后之分, 可以在声明函数前调用函数;// 无参函数
function sayHello() {
console.log(1 * 2)
}
// 调用
sayHello()
// 有参函数
function sayHello(x, y) {
console.log(x * y)
}
// 调用
sayHello(1, 2)
// 有返回值的函数
function sayHello(x, y) {
return x * y
}
// 调用
var value = sayHello(1, 2)
console.log(value)
// 有默认值的函数
function sayHello(x, y = 2) {
console.log(x * y)
}
sayHello(1) // y 没有设置值, 取默认值 2
sayHello(1, 3) // y 设置值, 取 3
// 作用域
function sayHello(x, y) {
var z = 3 // z 只能以函数体内调用, 不可以在函数外部调用
return x * y * z
}
function sayHello(x, y) {
z = 3 // z 只既可以函数体内调用, 又可以在函数外部调用
return x * y
}
sayHello(1, 2)
console.log(z) // 3
匿名函数可以将匿名函数赋值给一个变量或 事件, 使用匿名函数表达式时, 函数的调用语句, 必须放在函数声明语句之后。// 赋值给变量
var func = function() {
console.log('把函数赋值给变量')
}
// 调用
func()
// 赋值给事件
window.onload = function () {
console.log('把函数赋值给事件')
}
自执行函数!function(形参列表){}(实参列表), 可以使用多种运算开头, 但一般用感叹号!。!function(){
console.log(789)
}();
!function(num){
console.log(num)
}(789);
(function(形参列表){}(实参列表)), 使用()将函数及函数后设的小括号包裹起来。(function(){
console.log(789)
}())
(function(num){
console.log(num)
}(789))
(function(){})(), 使用 () 值包裹函数部分。(function(){
console.log(789)
})()
(function(num){
console.log(num)
})(789)
三种写法的特点:使用 ! 开头, 结构清晰, 不容易混乱, 推荐使用;能够表明匿名函数与调用的 () 为一个整体, 官方推荐使用;无法表明函数与之后的 () 的整体性, 不推荐使用;函数的内部属性arguments 对象用于储存调用函数时的所有实参, arguments是一个数组, 索引从 0 开始, 表示实参的个数, arguments.callee() 调用函数本身。在函数内部, 调用函数自身的写法叫做 递归。递归分为两部分:递 和 归。以递归调用语句为界限, 可以将函数分为上下两部分:递:将函数执行上半部分, 遇到自身的调用语句时, 继续进入内层函数, 再执行上半部分。知道执行完最内层函数。归:当最内层函数执行以后, 再从最内层函数开始, 逐渐执行函数的下半部分。当最外层函数执行时, 遇到自身的调用语句, 会进入内层函数执行, 而外层函数的后半部分暂不执行, 直到最内层函数执行完以后, 再逐步向外执行。function sayHello(x, y, z, t, k) {
console.log(arguments.length) // 5
for(let i of arguments) {
console.log(i) // 打印参数列表中参数的值
}
}
sayHello(1, 2, 3, 4, 5)
// 递归
var i = 1;
function sayHello(){
console.log(i);
i++;
if(i <= 4){
arguments.callee();
}
i--;
console.log(i);
}
sayHello(); // 1 2 3 4 4 3 2 1
下一节我们将认识一下Javascript的this}
一、Shell编程简介1.1 Shell的定义与功能Shell是一种命令行解释器,是在计算机操作系统中提供用户与操作系统交互的一种方式。通常Shell是指命令行界面,用户通过Shell界面可以输入命令并获得相应的操作结果。Shell的主要功能包括:解释和执行用户输入的命令:用户可以通过Shell界面输入各种命令,Shell会将这些命令解释并执行相应的操作。例如,用户可以输入ls命令来查看当前目录下的文件列表。管理和控制进程:Shell可以启动、停止、暂停和重启进程,还可以查看和管理当前正在运行的进程。例如,用户可以通过Shell启动一个后台进程,或者通过Shell杀死一个卡死的进程。文件和目录管理:Shell可以对文件和目录进行各种操作,如创建、删除、复制、移动、重命名等等。用户可以通过Shell在文件系统中进行各种操作。系统管理:Shell还可以管理和配置系统设置、环境变量、网络配置等等。例如,用户可以通过Shell配置网络连接,修改系统环境变量等等。1.1.1 Shell的作用Shell的主要作用有以下几个方面:提供命令行界面:Shell提供了一个命令行界面,用户可以通过键盘输入命令来与操作系统进行交互。这种交互方式相对于图形用户界面更加高效,可以让用户快速地完成各种操作。管理文件和目录:Shell可以对文件和目录进行各种操作,如创建、删除、复制、移动、重命名等等。用户可以通过Shell在文件系统中进行各种操作,例如创建文件夹、查看文件内容、修改文件权限等。执行各种命令和程序:用户可以通过Shell执行各种命令和程序,如编译代码、运行脚本、启动服务等。Shell会将用户输入的命令解释并执行相应的操作。管理进程和系统资源:Shell可以管理和控制进程,包括启动、停止、暂停和重启进程,还可以查看和管理当前正在运行的进程。同时,Shell还可以管理系统资源,如内存、CPU等。配置系统和环境:Shell可以管理和配置系统设置、环境变量、网络配置等等。用户可以通过Shell配置网络连接,修改系统环境变量等等。1.1.2 常见的Shell类型Bourne Shell(sh):Bourne Shell是Unix操作系统中最早的Shell,由Stephen Bourne开发。它是大多数Unix系统中默认的Shell,也是其他Shell的基础。Bourne Shell是一种比较简单的Shell,常用于编写Shell脚本和自动化任务。C Shell(csh):C Shell由Bill Joy开发,是一种比较高级的Shell。它具有C语言风格的语法和交互式命令历史功能,可以方便地编写复杂的Shell脚本和交互式应用程序。C Shell通常用于编写交互式应用程序和系统管理任务。Korn Shell(ksh):Korn Shell是由AT&T Bell实验室的David Korn开发的一种Shell,它是Bourne Shell的升级版,具有更加强大的编程功能。Korn Shell支持数组、函数、变量替换和命令行编辑等高级功能,也是Shell脚本编程中常用的一种Shell。Bash Shell(bash):Bash Shell是Bourne Again Shell的缩写,是由Brian Fox和Chet Ramey共同开发的一种Shell。它是Bourne Shell的增强版,与Bourne Shell基本兼容,但是具有更多的功能和特性,包括命令补全、历史命令、别名等。常见的Shell类型包括Bourne shell(/bin/sh)、Bash shell(/bin/bash)等。其中,Bash shell是Linux系统中应用最广泛的Shell类型,也是默认的Shell类型。1.2 Shell脚本的基本结构一般情况下,Shell脚本以文本文件的形式存在。Shell脚本由若干条命令和控制结构组成,可以在命令行中直接执行,也可以在脚本中进行批量处理。1.2.1 Shebang解释器声明Shebang是指在Unix或Linux系统中,位于脚本文件的第一行,以"#"和"!"两个字符组成的特殊语法。例如,#!/bin/bash就是一条Shebang语法,指示操作系统用bash解释器来执行后续的脚本命令。通俗地说,Shebang就是一种告诉操作系统如何解释执行脚本文件的语法。当操作系统执行一个脚本文件时,会首先读取文件的第一行,如果第一行以Shebang语法开头,就会根据指定的解释器来执行脚本文件中的命令。在Linux系统中,Shebang语法通常用于指定脚本的解释器类型,如bash、sh、python等等。它的作用是确保脚本文件能够在正确的环境中被执行,从而保证脚本的正确性和可靠性。从专业角度来讲,Shebang是一种在脚本文件中添加特殊标记以指定解释器类型的机制。在文件系统中,每个文件都有一个类型标识和可执行属性,而Shebang就是一种特殊的类型标识,它指定了脚本文件的解释器类型,使得系统可以正确地识别和执行脚本文件。除了指定解释器类型外,Shebang还可以添加参数和选项,以更加精确地控制脚本的执行行为。简短的讲,Shebang是指以"#!"开头的一行注释,它告诉系统使用哪个解释器来执行这个文件。在Linux中,常见的Shebang声明包括:#!/bin/bash
# 使用Bash shell解释器
#!/usr/bin/python3
# 使用Python 3解释器1.2.2 注释和文档Shell脚本中使用#符号来表示注释,注释可以用于说明脚本的功能、参数含义等相关信息。另外,Shell脚本还可以通过"Here Document"结构来定义多行文档:#!/bin/bash
<<EOF
这是一个Shell脚本示例
作者:张三
日期:2023-04-26
EOF1.2.3 可执行权限与执行方式为了让Shell脚本能够像普通命令那样执行,必须为其添加可执行权限。在终端中使用chmod命令来修改文件的权限:chmod +x script.sh然后就可以通过"./script.sh"或者"sh script.sh"等方式来执行Shell脚本。二、基本语法与命令2.1 变量与数据类型在Bash中,变量可以用来存储任意类型的数据。变量名由字母、数字和下划线组成,不能以数字开头。变量的赋值需要使用等号(=)操作符,等号两端不能有空格。例如:name="John"
age=252.1.1 变量定义与赋值变量的定义和赋值可以在一行完成,也可以分开进行。如果变量的值包含空格或其他特殊字符,需要使用引号将其括起来。例如:greeting="Hello World"
count=10
result=$((count + 5)) # 这里使用了算术表达式$(())2.1.2 变量引用与拓展在Bash中,可以通过在变量名前加上“$”符号来引用变量。例如:echo $name
# 输出 John还可以在变量名前加上“${}”来对变量进行拓展,以实现更高级的替换功能。例如:echo ${greeting} # 输出 Hello World
echo ${greeting/World/Universe} # 输出 Hello Universe2.1.3 环境变量环境变量是一种全局变量,可以在整个系统中被访问和修改。在Bash中,可以使用“export”命令将一个变量声明为环境变量。例如:export PATH=/usr/local/bin:$PATH2.2 控制结构2.2.1 条件判断在Bash中,可以使用“if”结构进行条件判断。其中,“fi”表示条件结束。例如:if [ $count -eq 10 ]; then
echo "Count is 10"
elif [ $count -gt 10 ]; then
echo "Count is greater than 10"
else
echo "Count is less than 10"
fi在上面的例子中,使用了“[ ]”来进行条件测试,其中“-eq”表示相等,“-gt”表示大于。2.2.2 循环结构在Bash中,可以使用“for”和“while”结构进行循环操作。例如:# for 循环
for i in {1..5}; do
echo $i
done
# while 循环
count=0
while [ $count -lt 5 ]; do
echo $count
count=$((count + 1))
done2.3 基本命令2.3.1 文件操作在Bash中,有许多命令可以用于文件操作。例如:# 创建目录
mkdir mydir
# 删除文件或目录
rm myfile
rm -r mydir
# 复制文件或目录
cp file1 file2
cp -r dir1 dir2
# 移动文件或目录
mv file1 file2
mv dir1 dir22.3.2 文本处理在Bash中,可以使用文本处理命令来对文本文件进行操作。例如:# 查看文件内容
cat myfile
# 查找文本
grep pattern myfile
# 替换文本
sed 's/pattern/replacement/g' myfile
# 排序
sort myfile2.3.3 系统管理在Bash中,可以使用系统管理命令来管理系统状态和配置。例如:# 查看进程状态
ps aux
# 查看系统资源使用情况
top
# 查看网络连接状态
netstat -a
# 修改文件权限
chmod 755 myfile下面是一个简单的表格,展示了一些常用的 Linux 命令及其用途:分类命令用途示例文件操作ls列出当前目录下的文件和子目录ls -l /path/to/directory文件操作cd改变当前工作目录cd /path/to/directory文件操作pwd显示当前工作目录的路径pwd文件操作mkdir创建一个新目录mkdir newdirectory文件操作rm删除一个文件或目录rm file.txt 或 rm -r directory文件操作cp复制一个文件或目录cp sourcefile destinationfile 或 cp -r sourcedir destinationdir文件操作mv移动或重命名一个文件或目录mv oldname newname 或 mv olddir newdir文件操作touch创建一个新文件或更新一个已存在文件的时间戳touch newfile.txt文件查看cat连接文件并打印到标准输出cat file.txt文件查看less分页查看文本文件的内容less file.txt文本处理grep在文件中搜索指定的字符串grep pattern file.txt文件查找find查找文件或目录find / -name filename.txt文件压缩tar打包、压缩和解压文件和目录tar -cvzf archive.tar.gz directory/ 或 tar -xvzf archive.tar.gz文件下载wget下载文件wget https://example.com/file.zip远程访问ssh远程登录到另一个计算机ssh username@hostname远程复制scp在本地主机和远程主机之间复制文件scp file.txt username@hostname:/remote/directory权限管理chmod修改文件权限chmod u=rw,go=r file.txt用户管理chown更改文件所有者chown username file.txt进程管理ps列出运行中的进程ps -e进程管理kill终止一个正在运行的进程kill PID系统监控top实时显示系统资源使用情况top三、函数与模块化3.1 函数的定义与调用在Bash中,可以使用“function”关键字或者省略关键字的方式来定义函数。例如:3.1.1 函数定义# 使用 function 关键字定义函数
function myfunc {
echo "Hello from myfunc"
}
# 省略 function 关键字
myfunc() {
echo "Hello from myfunc"
}3.1.2 函数调用函数调用时需要使用函数名和参数列表(如果有的话),参数之间用空格分隔。例如:myfunc arg1 arg23.2 函数参数与返回值3.2.1 传递参数在Bash中,可以通过位置变量来传递参数。例如,$1 表示第一个参数,$2 表示第二个参数,以此类推。例如:myfunc() {
echo "Hello $1 and $2"
}
myfunc Alice Bob上面的代码输出:Hello Alice and Bob在函数内部也可以使用特殊变量 $@ 或 $* 来获取所有传递的参数。例如:myfunc() {
echo "Arguments: $@"
}
myfunc Alice Bob Charlie上面的代码输出:Arguments: Alice Bob Charlie3.2.2 返回值在Bash中,函数返回值可以使用“return”命令来设置,返回值为一个非负整数。例如:myfunc() {
return 10
}
myfunc
echo "Return value: $?"上面的代码输出:Return value: 103.3 模块化编程3.3.1 脚本分离在Bash中,可以将脚本分解成多个文件,以实现模块化编程。例如,将一个函数定义保存在名为“lib.sh”的文件中:# 文件名:lib.sh
myfunc() {
echo "Hello from myfunc"
}然后在另一个脚本中导入该文件并调用函数:# 文件名:main.sh
source lib.sh
myfunc运行“main.sh”脚本即可输出:Hello from myfunc3.3.2 模块导入与使用在Bash中,可以通过“source”或“.”命令来导入其他脚本或库文件。例如:source lib.sh或者:. lib.sh这样就可以在当前脚本中使用被导入脚本中定义的函数和变量了。四、错误处理与调试4.1 错误处理与调试在Bash中,常见的错误包括语法错误、运行时错误和逻辑错误。下面分别介绍。4.1.1 语法错误语法错误通常是指脚本中出现了不符合 Bash 语法规范的语句,例如缺少引号、括号不匹配、变量名错误等等。这些错误会导致脚本无法正常执行。为了避免语法错误,可以使用 ShellCheck 等工具来检查代码。4.1.2 运行时错误运行时错误通常是指脚本在执行过程中出现了问题,例如文件不存在、权限不足、内存不足等等。为了避免这些错误,可以在脚本中使用条件语句进行判断,以确保程序能够正确地运行。同时,还可以使用 try-catch 或者 trap 命令来捕捉和处理异常。4.1.3 逻辑错误逻辑错误通常是指脚本的输出结果和预期不一致,例如变量赋值错误、循环条件错误、函数调用错误等等。为了避免逻辑错误,可以在编写脚本时进行严格的测试和校验,以确保程序的正确性。4.2 调试技巧与工具4.2.1 输出调试在 Bash 中,可以使用 echo 命令输出调试信息来查看程序的执行情况。例如:echo "Start of program"
myfunc
echo "End of program"4.2.2 使用set命令在 Bash 中,可以使用 set -x 命令来打开调试模式,这样所有执行的语句都会被输出到终端上。例如:set -x
myfunc
set +x4.2.3 使用调试器Bash 提供了内置的调试器——bashdb,它可以帮助我们更方便地调试 Bash 脚本。首先需要安装 bashdb,例如在 Ubuntu 系统上可以使用以下命令进行安装:sudo apt-get install bashdb然后在脚本文件中添加以下代码:#!/bin/bash -x
# 这里是脚本内容
myfunc最后运行以下命令即可进入调试模式:bashdb myscript.sh在调试模式下,可以使用类似 gdb 的命令来逐步执行脚本、查看变量值等等。示例:假设有一个名为 myscript.sh 的 Bash 脚本,需要进行调试。该脚本的内容如下:bash#!/bin/bash
echo "Starting the script..."
for i in {1..10}
do
if (( $i % 2 == 0 ))
then
echo "$i is even"
else
echo "$i is odd"
fi
done
echo "Script completed."这个脚本会输出从 1 到 10 的数字,并判断它们是奇数还是偶数。现在,我们想要使用 bashdb 来调试此脚本。首先,我们需要安装 bashdb。在 Ubuntu 系统中,可以使用以下命令来安装:sudo apt-get install bashdb安装完成后,我们可以使用以下命令启动 bashdb:bashdb myscript.sh然后,bashdb 将会显示与脚本相关的一些信息,并等待用户输入命令。接下来,我们可以使用 bashdb 提供的命令逐步执行脚本,并查看变量的值和程序流程。例如,我们可以使用 b 命令设置断点,然后使用 r 命令运行脚本,在遇到断点时停止。bashdb$ b 7
Breakpoint 1 at file myscript.sh, line 7
bashdb$ r
Starting the script...现在,脚本已经运行到第 7 行,并停在了断点处。我们可以使用 n 命令逐行执行代码,并使用 p 命令打印变量的值。bashdb$ n
for i in {1..10}
Breakpoint 1, file myscript.sh, line 7
bashdb$ p i
No value for i
bashdb$我们注意到,在第 7 行 i 的值还没有被赋值。我们可以继续使用 n 命令执行下一行,或者使用 s 命令进入函数或子程序中。当脚本完全执行完毕时,我们可以使用 q 命令退出 bashdb。五、实用技巧与最佳实践5.1 编码规范与风格5.1.1 代码可读性在编写 Bash 脚本时,应该尽可能提高代码的可读性。可以通过以下方式实现:使用注释来解释代码的作用和逻辑;使用空格、缩进等排版符号来使代码更易读;将代码分解成函数或模块以提高代码的重用性。5.1.2 统一风格在多人协作开发时,为了避免出现代码混乱不统一的情况,应该制定一套统一的编码规范和风格,并确保所有开发人员都能够按照这套规范进行编码。可以使用 shellcheck 等工具来检查代码是否符合规范。5.2 高效率编程技巧5.2.1 利用现有工具在编写 Bash 脚本时,可以利用现有的工具或库来提高程序的效率和可靠性。例如,可以使用 curl 命令从网络上获取数据,使用 jq 命令对 JSON 数据进行处理,使用 sed 和 awk 命令对文本进行处理等等。5.2.2 代码复用与优化为了提高代码的复用性和效率,可以将常用的功能封装成函数或模块,并将这些函数或模块放在库文件中,在需要的时候进行导入使用。同时,还可以优化程序性能,例如避免不必要的循环、缓存数据等等。5.3 安全性与稳定性5.3.1 权限管理在编写 Bash 脚本时,应该充分考虑脚本的安全性和稳定性。为了保护系统和数据的安全,应该严格控制脚本的执行权限,避免给予过高的权限。同时,还应该对输入参数进行校验和过滤,以避免注入攻击等安全问题。5.3.2 错误处理与日志记录为了保证程序的稳定性,应该编写健壮的错误处理代码,并对错误进行适当的处理或记录。可以将错误信息输出到终端或者记录到日志文件中,以便于调试和分析问题。同时,还应该在脚本中添加适当的检查点,以避免程序意外崩溃或死锁。六、实战案例与总结6.1 实战案例分析6.1.1 自动化部署Web项目脚本#!/bin/bash
# 定义变量
project_name="my-project"
git_repo="https://github.com/username/my-project.git"
project_dir="/var/www/html/my-project"
# 检查目录是否存在
if [ -d "$project_dir" ]; then
echo "Project directory already exists. Removing..."
rm -rf $project_dir
fi
# 克隆代码
echo "Cloning project from Git repo..."
git clone $git_repo $project_dir
# 切换到项目目录
cd $project_dir
exit
# 安装依赖
echo "Installing dependencies..."
npm install
# 构建代码
echo "Building project..."
npm run build
# 启动项目
echo "Starting project..."
pm2 start server.js --name $project_name
# 配置 Nginx 反向代理
echo "Configuring Nginx..."
sudo tee /etc/nginx/sites-available/$project_name <<EOF
server {
listen 80;
server_name test.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_cache_bypass \$http_upgrade;
}
}
EOF
# 检查 Nginx 配置是否正确
echo "Checking Nginx configuration..."
if sudo nginx -t; then
# 如果配置无误,启用配置并重启 Nginx
sudo ln -s /etc/nginx/sites-available/$project_name /etc/nginx/sites-enabled/
sudo systemctl restart nginx
echo "Deployment complete!"
else
# 如果配置有误,恢复原有状态
sudo rm /etc/nginx/sites-available/$project_name
rm -rf $project_dir
echo "Nginx configuration is invalid. Deployment failed."
fi
上面这是一个 Bash 脚本,用于自动化部署一个 Node.js 项目。脚本假设已经在服务器上安装了 Git、Node.js、npm、pm2 和 Nginx 等必要的工具和服务。该脚本执行以下步骤:定义了一些变量,包括项目名称、Git 仓库地址、项目路径等。检查项目目录是否存在,如果存在则删除。克隆代码到指定目录。进入项目目录,安装依赖。构建项目代码。启动项目。配置 Nginx 反向代理。检查 Nginx 配置是否正确,如果正确,则启用配置并重启 Nginx;否则,恢复原有状态并输出错误信息。6.1.2 自动化部署Docker项目脚本#!/bin/bash
# 定义变量
project_name="my-project"
docker_repo="username/my-project"
docker_tag="latest"
docker_network="my-network"
data_volume="$PWD/data:/app/data"
log_volume="$PWD/logs:/var/log/nginx"
# 检查容器是否存在
if [ "$(docker ps -q -f name=$project_name)" ]; then
echo "Container already exists. Stopping and removing..."
docker stop $project_name && docker rm $project_name
fi
# 创建 Docker 网络
if ! $(docker network ls
grep -q $docker_network); then
echo "Network not found. Creating..."
docker network create $docker_network
fi
# 拉取 Docker 镜像
echo "Pulling Docker image..."
docker pull $docker_repo:$docker_tag
# 启动 Docker 容器
echo "Starting Docker container..."
docker run \
--name $project_name \
--network $docker_network \
-v $data_volume \
-v $log_volume \
-p 80:80 \
-d $docker_repo:$docker_tag
# 检查容器是否成功启动
echo "Checking container status..."
if [ "$(docker ps -q -f name=$project_name -f status=running)" ]; then
echo "Deployment complete!"
else
# 如果容器启动失败,则删除容器和网络,并输出错误信息
docker stop $project_name && docker rm $project_name
docker network rm $docker_network
echo "Failed to start container. Deployment failed."
fi是一个 Bash 脚本,用于自动化部署 Docker 项目。该脚本会执行以下步骤:定义一些变量,包括项目名称、Docker 镜像仓库地址、标签等。检查容器是否已经存在,如果存在则先停止并删除容器。创建 Docker 网络(如果尚未创建),用于与其他容器通信。从 Docker 仓库中拉取指定的镜像。启动 Docker 容器,并挂载数据卷和日志卷,并将容器端口映射到主机端口上。检查容器是否成功启动。以上脚本还包含了在容器启动失败时的处理逻辑,即删除容器和网络,并输出错误信息。需要注意的是,在使用该脚本前,需要确保系统已经安装 Docker 并具备相关管理权限。6.1.3 系统监控与报警#!/bin/bash
# 定义变量
cpu_threshold=80
mem_threshold=80
email_recipient="admin@example.com"
email_subject="System Alert"
# 获取 CPU 使用率和内存使用率
cpu_usage=$(top -b -n1
grep "Cpu(s)"
awk '{print $2}')
mem_usage=$(free
awk '/Mem/{ printf("%d\n"), $3/$2*100 }')
# 判断 CPU 和内存使用率是否超过阈值
if [ "$cpu_usage" -gt "$cpu_threshold" ]
[ "$mem_usage" -gt "$mem_threshold" ]; then
# 如果超过阈值,则发送邮件告警
email_body="CPU usage: $cpu_usage%, Mem usage: $mem_usage%"
sendmail -t <<EOF
From: "System Monitoring" <no-reply@example.com>
To: $email_recipient
Subject: $email_subject
$email_body
EOF
fi以上脚本会在定时任务中运行,每隔一段时间获取当前系统的 CPU 使用率和内存使用率,并将它们与预设的阈值进行比较。如果超过阈值,则通过邮件等方式发出告警信息。6.1.4 shell写一个Linux管理系统#!/bin/bash
# 判断系统类型,选择合适的包管理器
if [ -n "$(command -v yum)" ]; then
PKGMGR="yum"
elif [ -n "$(command -v apt-get)" ]; then
PKGMGR="apt-get"
else
echo "无法确认系统类型,请手动安装软件包。"
exit 1
fi
# 安装必需的工具和软件包
for TOOL in curl tar zstd unzip; do
if ! command -v $TOOL > /dev/null; then
sudo $PKGMGR install -y $TOOL
fi
done
# 菜单文字提示
function menu() {
cat << EOF
=========================================
Linux 系统管理工具
=========================================
1. 进程管理
2. 磁盘管理
3. 网络管理
4. 日志分析
5. 用户管理
6. 安全管理
7. 系统信息
8. 定时任务
0. 退出
=========================================
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
}
# 进程管理
function process_mgmt() {
while true
do
cat << EOF
-----------------------------------------
进程管理
-----------------------------------------
1. 列出所有进程
2. 杀死指定进程
3. 按照端口杀死进程
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
ps aux
;;
2)
read -p "请输入要杀死的进程 ID:" PID
kill $PID
;;
3)
read -p "请输入要杀死的端口号:" PORT
sudo fuser -k $PORT/tcp
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 磁盘管理
function disk_mgmt() {
while true
do
cat << EOF
-----------------------------------------
磁盘管理
-----------------------------------------
1. 查看磁盘使用情况
2. 清理磁盘空间
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
df -h
;;
2)
read -p "请输入要清理的文件路径:" PATH
sudo find $PATH -type f -mtime +30 -delete
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 网络管理
function network_mgmt() {
while true
do
cat << EOF
-----------------------------------------
网络管理
-----------------------------------------
1. 查看网络连接
2. 配置网络接口
3. 查询端口信息
4. 扫描局域网设备
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
netstat -anp
;;
2)
sudo nano /etc/network/interfaces
;;
3)
read -p "请输入要查询的端口号:" PORT
sudo lsof -i:$PORT
;;
4)
read -p "请输入 IP 地址范围(例如:192.168.1.1/24):" IP_RANGE
sudo nmap -sP $IP_RANGE
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 日志分析
function log_analysis() {
while true
do
cat << EOF
-----------------------------------------
日志分析
-----------------------------------------
1. 查看系统日志
2. 筛选关键字
3. 保存日志
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
cat /var/log/syslog
;;
2)
read -p "请输入要筛选的关键字:" KEYWORD
cat /var/log/syslog
grep $KEYWORD
;;
3)
read -p "请输入要保存的文件路径:" FILEPATH
cat /var/log/syslog > $FILEPATH
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 用户管理
function user_mgmt() {
while true
do
cat << EOF
-----------------------------------------
用户管理
-----------------------------------------
1. 查看用户列表
2. 添加用户
3. 删除用户
4. 修改用户密码
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
cat /etc/passwd
;;
2)
read -p "请输入新用户的用户名:" USERNAME
sudo adduser $USERNAME
;;
3)
read -p "请输入要删除的用户的用户名:" USERNAME
sudo userdel -r $USERNAME
;;
4)
read -p "请输入要修改密码的用户名:" USERNAME
sudo passwd $USERNAME
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 安全管理
function security_mgmt() {
while true
do
cat << EOF
-----------------------------------------
安全管理
-----------------------------------------
1. 修改 SSH 端口
2. 禁止 ROOT 登录
0. 返回上一级菜单
-----------------------------------------
EOF
read -p "请输入数字选择相应的菜单:" CHOICE
case $CHOICE in
1)
read -p "请输入新的 SSH 端口号:" PORT
sudo sed -i "s/Port .*/Port $PORT/g" /etc/ssh/sshd_config
sudo service sshd restart
;;
2)
sudo sed -i "s/PermitRootLogin yes/PermitRootLogin no/g" /etc/ssh/sshd_config
sudo service sshd restart
;;
0)
break
;;
*)
echo "错误的选择。"
;;
esac
done
}
# 系统信息
function system_info() {
cat << EOF
=========================================
系统信息
=========================================
操作系统:$(lsb_release -d
cut -f2-)
内核版本:$(uname -r)
CPU 信息:$(grep "model name" /proc/cpuinfo
head -n1
cut -d: -f2-)
内存信息:$(free -h
awk 'NR==2 {print $2}')
磁盘信息:$(df -h
awk '$NF=="/" {print "总容量:" $2 ", 剩余容量:" $4}')
=========================================
EOF
}
# 定时任务
function cron_job() {
crontab -l
}
# 主循环
while true
do
menu
case $CHOICE in
1)
process_mgmt
;;
2)
disk_mgmt
;;
3)
network_mgmt
;;
4)
log_analysis
;;
5)
user_mgmt
;;
6)
security_mgmt
;;
7)
system_info
;;
8)
cron_job
;;
0)
echo "谢谢使用,再见!"
exit 0
;;
*)
echo "错误的选择。"
;;
esac
done
6.1.5
shell写一个Docker管理系统#!/bin/bash
# 判断操作系统类型
OS_TYPE=$(awk -F= '/^NAME/{print $2}' /etc/os-release)
# 输出菜单
function show_menu() {
echo "========================================="
echo "
Docker 管理脚本"
echo "========================================="
echo "
1. 查询 Docker 版本"
echo "
2. 查询 Docker 状态"
echo "
3. 开启 Docker"
echo "
4. 关闭 Docker"
echo "
5. 重启 Docker"
echo "
6. 查询镜像列表"
echo "
7. 拉取镜像或重新拉取镜像"
echo "
8. 删除镜像"
echo "
9. 执行容器命令"
echo " 10. 显示所有容器信息"
echo " 11. 删除所有容器"
echo " 12. 退出"
echo "========================================="
}
# 检查用户输入是否合法
function check_input() {
while true; do
read -p "请输入您的选择(输入数字):" choice
case $choice in
[1-9]|10|11|12)
break
;;
*)
echo "无效的选择,请重新输入!"
;;
esac
done
}
# 检查 Docker 状态
function check_docker_status() {
systemctl status docker
grep "Active: active (running)" &> /dev/null
if [ $? -eq 0 ]; then
echo "Docker 正在运行!"
return 0
else
echo "Docker 已停止运行!"
return 1
fi
}
# 启动 Docker
function start_docker() {
systemctl start docker
if [ $? -eq 0 ]; then
echo "Docker 启动成功!"
return 0
else
echo "Docker 启动失败!"
return 1
fi
}
# 停止 Docker
function stop_docker() {
systemctl stop docker
if [ $? -eq 0 ]; then
echo "Docker 停止成功!"
return 0
else
echo "Docker 停止失败!"
return 1
fi
}
# 重启 Docker
function restart_docker() {
systemctl restart docker
if [ $? -eq 0 ]; then
echo "Docker 重启成功!"
return 0
else
echo "Docker 重启失败!"
return 1
fi
}
# 查询 Docker 版本
function check_docker_version() {
docker version &> /dev/null
if [ $? -eq 0 ]; then
echo "当前 Docker 版本为:"
docker version
grep Version
return 0
else
echo "查询 Docker 版本失败!"
return 1
fi
}
# 查询镜像列表
function list_images() {
docker images
}
# 拉取镜像或重新拉取镜像
function pull_image() {
read -p "请输入要拉取的镜像名称(如ubuntu):" image_name
read -p "请输入要拉取的镜像版本(如18.04):" image_version
sudo docker pull $image_name:$image_version
if [ $? -eq 0 ]; then
echo "镜像 $image_name:$image_version 拉取成功!"
return 0
else
echo "镜像 $image_name:$image_version 拉取失败!"
return 1
fi
}
# 删除指定的镜像
function delete_image() {
read -p "请输入要删除的镜像名称和版本(如ubuntu:18.04):" image_tag
sudo docker rmi $image_tag
if [ $? -eq 0 ]; then
echo "镜像 $image_tag 删除成功!"
return 0
else
echo "镜像 $image_tag 删除失败!"
return 1
fi
}
# 执行容器命令
function exec_container() {
echo "请选择一个容器:"
docker ps -a
while true; do
read -p "请输入容器 ID:" container_id
docker ps -a --filter "id=$container_id" &> /dev/null
if [ $? -eq 0 ]; then
break
else
echo "无效的容器 ID,请重新输入!"
fi
done
echo "请输入要执行的命令:"
read -e command
docker exec -it $container_id $command
}
# 显示所有容器信息
function show_containers() {
docker ps -a
}
# 删除所有停止运行的容器
function delete_containers() {
docker ps -a --filter "status=exited" --format "{{.ID}}"
xargs -r docker rm
echo "所有已停止的容器已删除!"
}
# 主函数
function main() {
while true; do
show_menu
check_input
case $choice in
1)
check_docker_version
;;
2)
check_docker_status
;;
3)
if check_docker_status; then
echo "Docker 已经在运行,无需重复启动!"
else
start_docker
fi
;;
4)
if check_docker_status; then
stop_docker
else
echo "Docker 已经停止,无需重复关闭!"
fi
;;
5)
if check_docker_status; then
restart_docker
else
echo "Docker 已经停止,无法执行重启操作!"
fi
;;
6)
list_images
;;
7)
pull_image
;;
8)
delete_image
;;
9)
exec_container
;;
10)
show_containers
;;
11)
delete_containers
;;
12)
exit 0
;;
*)
echo "无效的选择,请重新输入!"
;;
esac
read -n1 -r -p $'按任意键返回菜单...\n' key
done
}
# 检查操作系统类型是否支持
if [[ "$OS_TYPE" =~ "Ubuntu" ]]
[[ "$OS_TYPE" =~ "CentOS" ]]; then
main
else
echo "不支持的操作系统类型!"
fi6.1.6
shell写一个自动化构建Docker镜像脚本#!/bin/bash
# 检查 Docker 是否已安装
if ! [ -x "$(command -v docker)" ]; then
echo '错误:Docker 未安装,请先安装 Docker!' >&2
exit 1
fi
# 检查 Docker 是否正在运行
if ! systemctl is-active docker > /dev/null; then
echo '错误:Docker 已停止,请先启动 Docker!' >&2
exit 1
fi
# 检查脚本是否在 JAR 包所在目录下运行
CURRENT_DIR=$(pwd)
if [ $(ls *.jar 2>/dev/null
wc -l) -eq 0 ]; then
echo "错误:当前目录下没有 JAR 包,请将 JAR 包放入该目录再运行此脚本!" >&2
exit 1
fi
# ---- 用户自定义变量 ----
read -p "请输入项目名称:" PROJECT_NAME
JARS=($(ls *.jar))
# 列出当前目录下的所有 JAR 包供用户选择
if [ ${#JARS[@]} -eq 0 ]; then
echo "错误:当前目录下没有 JAR 包,请将 JAR 包放入该目录再运行此脚本!" >&2
exit 1
fi
echo "请选择 JAR 包(输入对应的编号):"
for i in "${!JARS[@]}"; do
echo "$((i+1)). ${JARS[$i]}"
done
read -p "请输入选择的编号(默认为1):" JAR_INDEX
JAR_INDEX=${JAR_INDEX:-"1"}
JAR_FILE=${JARS[$((JAR_INDEX-1))]}
read -p "请输入镜像名称(默认为 ${PROJECT_NAME}):" IMAGE_NAME
read -p "请输入初始镜像版本号(默认为 1.0.0):" IMAGE_VER
read -p "请输入暴露端口号(默认为 8080):" EXPOSE_PORT
read -p "请输入维护者信息(示例:Your Name <your.email@example.com>):" MAINTAINER
# 处理用户输入
IMAGE_NAME=${IMAGE_NAME:-"${PROJECT_NAME}"}
IMAGE_VER=${IMAGE_VER:-"1.0.0"}
EXPOSE_PORT=${EXPOSE_PORT:-"8080"}
MAINTAINER=${MAINTAINER:-"Your Name <your.email@example.com>"}
# 新建 Dockerfile 子目录
DOCKERFILE_DIR=dockerfile
if [ ! -d "$DOCKERFILE_DIR" ]; then
echo "正在创建目录 $DOCKERFILE_DIR..."
mkdir -p "$DOCKERFILE_DIR"
fi
# 根据版本号递增生成镜像标签
if docker images "${IMAGE_NAME}:${IMAGE_VER}" &> /dev/null; then
echo "镜像 ${IMAGE_NAME}:${IMAGE_VER} 已存在,自动递增版本号..."
i=0
while docker images "${IMAGE_NAME}:${IMAGE_VER}-$((i+1))" &> /dev/null; do
let i++
done
IMAGE_TAG="${IMAGE_VER}-$((i+1))"
else
IMAGE_TAG="${IMAGE_VER}"
fi
# 自动生成 Dockerfile 文件
DOCKERFILE_PATH="${DOCKERFILE_DIR}/${IMAGE_NAME}-${IMAGE_TAG//./_}.Dockerfile"
DOCKERFILE=$(cat << EOF
FROM openjdk:8-jre-alpine
LABEL maintainer="${MAINTAINER}"
COPY ${JAR_FILE} /app/${PROJECT_NAME}.jar
EXPOSE ${EXPOSE_PORT}
CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/${PROJECT_NAME}.jar"]
EOF
)
echo "$DOCKERFILE" > "$DOCKERFILE_PATH"
# 构建 Docker 镜像
docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" -f "$DOCKERFILE_PATH" .
if [ $? -eq 0 ]; then
echo "Docker 镜像构建成功!"
echo "镜像名称:${IMAGE_NAME}:${IMAGE_TAG}"
else
echo "Docker 镜像构建失败!"
fi
这个脚本用于自动化构建 Docker 镜像,其中包括以下步骤:检查 Docker 是否已安装,并且是否正在运行。检查脚本是否在 JAR 包所在目录下运行,并列出当前目录下的所有 JAR 包供用户选择。根据用户输入的信息,生成 Dockerfile 文件并自动构建 Docker 镜像。具体来说,这个脚本首先使用 command -v 命令检查 Docker 是否已经安装,并通过 systemctl is-active 命令检查 Docker 是否正在运行。如果 Docker 未安装或停止运行,则会输出错误提示并退出脚本。然后,脚本会检查是否有 JAR 包存在,并列出可用的 JAR 包供用户选择。用户可以根据输出结果输入相应的编号,选择需要构建 Docker 镜像的 JAR 包。脚本还会要求用户输入一些必要的信息,例如镜像名称、版本号、暴露端口等。接着,脚本会根据用户输入的信息,生成 Dockerfile 文件并自动构建 Docker 镜像。Dockerfile 文件是根据用户输入的信息和模板内容自动生成的,其中包含了从官方的 OpenJDK 8 运行时镜像中获取 JRE,将 JAR 包复制到容器中,设置暴露端口等指令。脚本还会根据版本号递增生成镜像标签,以避免重复命名的冲突。最后,脚本会输出构建结果,并显示构建成功的 Docker 镜像名称和版本号等信息。6.1.7 shell写一个定时执行python脚本的脚本#!/bin/bash
# 设置 Python 脚本文件路径和执行频率
PYTHON_SCRIPT="/path/to/script.py"
CRON_SCHEDULE="0 0 * * *"
# 添加任务到 crontab 中
(crontab -l ; echo "$CRON_SCHEDULE python3 $PYTHON_SCRIPT")
crontab -
echo "已添加 Python 脚本定时任务:$CRON_SCHEDULE $PYTHON_SCRIPT"
6.2 学习资源与进阶方向6.2.1 在线教程与书籍推荐《鸟哥的 Linux 私房菜(第四版)》:这是一本非常全面的 Linux 入门书籍,其中有很多详细的 Shell 教程,适合初学者入门。《Linux 命令行大全(第二版)》:这是一本综合Linux命令行的书籍,其中有很多关于Shell解释的内容。慕课网教程:慕课网为大家提供了一些针对初学者的 Shell 教程,覆盖了常用的 Shell 命令和编程语言。菜鸟教程:菜鸟教程是一个非常好的计算机学习网站,其中包括了很多可以在线学习的 Shell 教程,适合新手入门。https://www.runoob.com/linux/linux-shell.html总之,无论是书籍、视频教程还是在线社区,都提供了很多 Shell 学习资源和帮助,只有通过不断的实践和学习,才能够逐渐掌握这个强大的工具。}

我要回帖

更多关于 c语言怎么调用函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信