shell --函数

 基本的函数概念

 函数定义
menu()         
{
echo "/$1 is $1"
echo "this is $2"
reture 9
函数内内语句也无分号;
}
 函数调用menu aa bb
和C语言不同,执行函数不带括号()
 函数返回值menu aa bb
result=$?
echo "$result”


 

  函数名中间不能带杠
#!/bin/bash
verify-para()
{
}   
[macg@machome ~]$ sh test.sh
test.sh: line 18: `verify-para': not a valid identifier


    shell函数定义必须在函数调用之前,因为shell是个顺序解释程序

#!/bin/bash

verifypara                    调用

host=$1
user=$2
passwd=$3

verifypara()
{
if (( $# != 3 )); then
    echo "usage: $0 $host $user $passwd"   定义
    exit 1
fi
}   
[macg@machome ~]$ sh test.sh 192.168.1.12 macg 008421
test.sh: line 3: verifypara: command not found

 

    注意函数退出用return,不能用exit,exit是直接退出程序
exit 不止退出函数,而是直接退出shell script,

 
    不能用中括号条件表示式在if语句中引用函数,必须用命令/函数直接作为条件的方式在if语句中引用函数
这种方式在C语言中支持,但shell脚本中不支持

if [ getyn=1 ]
then
echo " your answer is no "
else
echo "your anser is yes "
fi
[macg@mac-home ~]$ sh test.sh
input the num:
3
your answer is no     根本没执行函数getyn


    也不能用赋值语句引用函数 

yn=getyn
if [ yn=1 ]
then
echo " your answer is no "
else
echo "your anser is yes "
fi
[macg@mac-home ~]$ sh test.sh
input the num:
3
your answer is no  根本没执行函数




简单的说,函数就只能象command一样被直接执行,不能放在条件表达式或赋值语句里


    Shell的函数参数就和命令行参数一样,也是$1,$2,$n

menu()        
{
echo "/$1 is $1"
echo "this is $2"
reture 9
}

menu aa bb  
[root@machome macg]# sh test.sh
$1 is aa
this is bb

当调用一个函数时,shell主程序的参数,$*,$@,$#,$1,$2等等将会被函数中的参数所替换.即函数中,$1,$2,$3是函数参数,$#是参数个数


    总之,函数和command几乎一模一样
    只能直接执行,不能用在赋值语句或if表达式里
    函数参数和命令行参数格式相同
    也有返回值,返回值变量也是$?



<think> 我们正在讨论Makefile中的内容。用户询问了`shell-basename`是什么。在Makefile中,`shell-basename`通常是一个自定义的函数,用于从文件路径中提取基名(即路径的最后一部分)。它可能通过Makefile内置函数实现,也可能通过调用shell命令实现。 由于Makefile本身没有内置的`shell-basename`函数,因此我们需要考虑两种常见的实现方式: 1. 使用Makefile内置函数`notdir`。 2. 通过`shell`函数调用系统的`basename`命令。 下面我将详细解释这两种实现方式,并给出代码示例。 </think> ### `shell-basename` 详解 `shell-basename` 是一个自定义的 Makefile 函数,用于从文件路径中提取最末尾的部分(通常称为"基名")。它模拟了 Unix/Linux 系统中 `basename` 命令的功能,但完全在 Makefile 环境中实现。 #### 典型实现方式 ```makefile # 实现方式1:使用Makefile内置函数 define shell-basename $(notdir $(1)) endef # 实现方式2:通过shell命令实现 define shell-basename $(shell basename $(1)) endef # 实现方式3:带后缀移除功能 define shell-basename $(shell basename $(1) $(2)) endef ``` #### 功能说明 | 参数 | 描述 | |------|------| | `$(1)` | 必需:文件或目录的完整路径 | | `$(2)` | 可选:要移除的文件后缀(仅在方式3中有效) | #### 工作流程 ```mermaid graph TD A[输入路径] --> B{实现方式} B -->|方式1| C[使用notdir函数] B -->|方式2/3| D[调用shell basename命令] C --> E[返回路径最后部分] D --> F[返回路径最后部分] E --> G[输出基名] F --> G ``` #### 示例比较 假设输入路径为 `/home/user/project/src/module.c` | 实现方式 | 调用代码 | 输出结果 | |----------|----------|----------| | 方式1 | `$(call shell-basename,/home/user/project/src/module.c)` | `module.c` | | 方式2 | 同上 | `module.c` | | 方式3 (带后缀) | `$(call shell-basename,/home/user/project/src/module.c,.c)` | `module` | #### 完整使用示例 ```makefile # 定义shell-basename函数(方式1) define shell-basename $(notdir $(1)) endef # 定义带后缀移除的函数(方式3) define shell-basename-with-suffix $(shell basename $(1) $(2)) endef # 测试路径 TEST_PATH := /path/to/example_file.txt # 测试函数 test: @echo "方式1输出: $(call shell-basename,$(TEST_PATH))" @echo "方式3输出: $(call shell-basename-with-suffix,$(TEST_PATH),.txt)" @echo "方式3无后缀: $(call shell-basename-with-suffix,$(TEST_PATH))" ``` **执行结果**: ``` 方式1输出: example_file.txt 方式3输出: example_file 方式3无后缀: example_file.txt ``` ### 技术细节说明 #### 1. `notdir` vs `basename` 命令 | 特性 | `notdir` (Makefile) | `basename` (shell) | |------|---------------------|--------------------| | 依赖 | 纯Makefile实现 | 依赖外部shell环境 | | 性能 | 更快(无进程创建) | 较慢(需创建shell进程) | | 后缀处理 | 无法移除后缀 | 可指定后缀自动移除 | | 路径格式 | 自动处理路径分隔符 | 依赖系统路径格式 | | 跨平台 | 完全跨平台 | 在Windows上可能失效 | #### 2. 路径处理规则 - 移除所有前导目录部分 - 保留最后一部分 - 处理特殊情况: - 路径以斜杠结尾:`/path/dir/` → `dir` - 路径为根目录:`/` → `/` - 空路径:保留为空 #### 3. 后缀处理规则(仅方式3) - 后缀必须完全匹配(区分大小写) - 如果后缀不匹配,返回完整文件名 - 仅移除最后一个后缀: - `file.tar.gz` → `basename file.tar.gz .gz` → `file.tar` - 支持多个后缀: ```makefile define remove-extensions $(call shell-basename,$(1),.c)$(call shell-basename,$(1),.h) endef ``` ### Android构建系统中的应用 在Android NDK构建系统中,典型的模块命名模式: ```makefile LOCAL_PATH := $(call my-dir) define module_base_name $(call shell-basename,$(LOCAL_PATH)) endef LOCAL_MODULE := $(module_base_name)_shared ``` ### 最佳实践建议 1. **跨平台实现**: ```makefile ifeq ($(OS),Windows_NT) define shell-basename $(notdir $(subst \,/,$(1))) endef else define shell-basename $(notdir $(1)) endef endif ``` 2. **带默认后缀移除**: ```makefile define smart-basename $(if $(2), \ $(shell basename $(1) $(2)), \ $(notdir $(1)) \ ) endef ``` 3. **错误处理增强**: ```makefile define safe-basename $(if $(1), \ $(notdir $(1)), \ $(error Invalid path provided) \ ) endef ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值