【LINUX】在 linux 上执行命令和编程程序/脚本需要知道的细节



1. sh -c 的必要性

本节 转自 ? https://blog.csdn.net/bobchill/article/details/84647575

在Linux使用 echo 并配合命令重定向是实现向文件中写入信息的快捷方式。

比如要向 test.asc 文件中随便写入点内容,可以:

$ echo "信息" > test.asc
# 或者
$ echo "信息" >> test.asc

下面,如果将 test.asc 权限设置为只有 root 用户才有权限进行写操作:
$ sudo chown root.root test.asc
然后,我们使用 sudo 并配合 echo 命令再次向修改权限之后的 test.asc 文件中写入信息:
$ sudo echo "又一行信息" >> test.asc
命令执行结果:
-bash: test.asc: Permission denied

这时,可以看到 bash 拒绝这么做,说是权限不够。这是因为重定向符号 “>” 和 “>>” 也是 bash 的命令。
我们使用 sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 和 “>>” 命令也具有 root 权限,所以 bash 会认为这两个命令都没有像 test.asc 文件写入信息的权限。

解决这一问题的途径有两种。第一种是利用 “sh -c” 命令,它可以让 bash 将一个字串作为完整的命令来执行,这样就可以将 sudo 的影响范围扩展到整条命令。具体用法如下:
$ sudo sh -c 'echo "又一行信息" >> test.asc'

另一种方法是利用管道和 tee 命令,该命令可以从标准输入中读入信息并将其写入标准输出或文件中,具体用法如下:
$ echo "第三条信息" | sudo tee -a test.asc

注意,tee 命令的 “-a” 选项的作用等同于 “>>” 命令,如果去除该选项,那么 tee 命令的作用就等同于 “>” 命令。



2. 程序的环境变量与“终端”的环境变量异同

2.1 终端环境变量

我们在终端中执行脚本/程序、命令工具(是脚本/程序)(下面统称程序),这些程序会被设置环境变量。

只针对终端而言的环境变量,可以通过 $HOME/.bashrc 来设置。这是通常教程,网络资源中最常见的方式。

但是 .bashrc 实际上是对 bash 程序而言的 - 是的,终端窗口上运行的本身也就是一个程序 - bash 程序。
所以,有的朋友为了提高效率、为了观感,而选择不同的 shell 软件 - 如 ZSH。如果运行的是 ZSH,那么 .bashrc 中用户自定义设置的环境变量就没有用了。而是需要加入到 $HOME/.zshrc 文件中。

2.2 So, Global Environment Variables?

当我们去了解 LINUX 的环境变量的时候,/etc/profile / /etc/environment 也是经常被提到的。
但是在我这里过多不会介绍它们,因为修改这几个文件都是不建议的方式(当你真正有需要修改系统全局变量的时候,只要知道 /etc/profile 这个路径即可,怎么改?有什么影响?自然到时候就知道了)。

2.3 User-Global Environment Variables?

如果你是一个 coder,有时候需要使用第三方厂商提供的 API 接口 ——需要注册账号,申请 key;同时你又想要将编写的程序开源。
于是每次都要在代码中修改(删除) key 之后再 commit 代码。

No, no, no! 我们可以通过环境变量解决这个问题。在 Python 中,通过以下两行代码就可以取到环境变量值:

import os
VENDOR_KEY = os.environ.get("VENDOR_KEY")

即,我们只需要配置 VENDOR_KEY,然后按平常运行程序即可,此时程序就能取得环境变量,得到正确的 KEY 值。
如果该程序是在命令行中运行的,那么可以根据 2.1 节中修改 $HOME/.<shell-program>rc 文件即可。
但是有的程序是 desktop GUI,换句话说,我们想要修改一处地方,使这个环境变量对登录的用户(如’自己‘)执行的任意程序都有效。

那么我们应该修改 $HOME/.profile 这个文件。

...

export VENDOR_KEY=the-key-value

修改文件之后不会马上就生效。我们可以通过 <用户> ->“注销” -> 重新登录来使环境变量生效。

2.4 应用程序(desktop GUI)环境变量

其实在写 2 环境变量 的时候,我实在不确定应该将内部小节的顺序如何放置。
因为这就好像是先有鸡还是先有蛋的问题。不过内容不长,所以顺序上还是顺便就好,因为这些内容前后节都是直接关联的。

正如前面小节说到的,如果我们只修改如 $HOME/.bashrc,那么它只会对 BASH 程序有效。而 BASH 程序就是终端窗口内运行的程序 - 用于执行命令行程序(环境变量如果没有在程序内修改的化,那么程序就会继承它父进程的环境变量),从 bash 内被执行的程序能够拥有和 bash 一样的环境变量;但是对于在 desktop 环境中双击执行的程序就不能拥有这些环境变量了。
LINUX 可以安装不同的 desktop 程序,如 KDE,Gnome 等等,所以我们也不应该去想只修改该桌面的环境变量。还是一步到位,直接修改上一节提到的 $HOME/.profile 对本用户的所有程序有效。包括终端程序。



3. “宏”(预定义符号)

“宏”含义“真实”值
EOF数据流结束,无更多数据-1
...


4. 文件描述符

4.1 Too many open filej

(C 语言)如果调用 fopen 打开某个文件 "r",得到 NULL,未必是文件不存在。
如果直接在代码中写:

const char *file = "/<path>/<to>/some_file.txt";
FILE *fp = NULL;
if ((fp=open(file, "r")) == NULL) {
    fprintf(stderr, "%s not exist.", file);
    exit(1);
}

// do real read stuff

fclose(fp);

写出这种代码不算最糟糕的,但是也属于几乎不可用的代码。
因为如果一个程序中的其它地方有打开其它文件,但是 coder 忘记 fclose,而这是一个"daemon" 进程的话。
那么如果上面位置 open fail,此时实际错误是进程允许的最大文件描述符被用光。而非是文件不存在。
所以这么写代码反而有严重的误导性,而原本需要修改的地方也并非这里。

更好的写法:

const char *file = "/<path>/<to>/some_file.txt";
FILE *fp = NULL;
if ((fp=open(file, "r")) == NULL) {
    perror(file);
    exit(1);
}

// do real read stuff

fclose(fp) ? perror(file) : (fp = NULL);

// maybe more code under ...



5. 链接库

5.1 动态链接库 – .so

查看二进制程序或 .so 使用到的 .so:
使用 ldd 工具:

# ldd /usr/bin/iwinfo 
        /lib/ld-musl-arm.so.1 (0x54b71000)
        libuci.so => /lib/libuci.so (0x76f9f000)
        libubox.so => /lib/libubox.so (0x76f86000)
        libubus.so => /lib/libubus.so (0x76f71000)
        libiwinfo.so => /usr/lib/libiwinfo.so (0x76f57000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x76f3c000)
        libc.so => /lib/ld-musl-arm.so.1 (0x54b71000)
# 
# ldd /usr/lib/lua/iwinfo.so 
        ldd (0x54b36000)
        libuci.so => /lib/libuci.so (0x76ef2000)
        libubox.so => /lib/libubox.so (0x76ed9000)
        libubus.so => /lib/libubus.so (0x76ec4000)
        libiwinfo.so => /usr/lib/libiwinfo.so (0x76eaa000)
        liblua.so.5.1.5 => /usr/lib/liblua.so.5.1.5 (0x76e7b000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x76e60000)
        libc.so => ldd (0x54b36000)

#

查看 .so 文件接口:

$ nm -D xxx.so
...

打包成 .so:

n/a

5.2 静态链接库 – .a

查看 .a 文件都包含了哪些文件:

$ ar -t xxx.a
...

使用 ar 命令打包:

n/a




Reference



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值