Blog

sticky-bit位

Content #

目录 #

标识了Sticky Bit的目录对于该目录下文件的删除和重命名有特殊限制:

(目录的w权限 and (是文件的所有者 or 是目录的所有者 or 是超级用户))

也就是说,当一个目录设置sticky-bit位后,存放在该目录下的文件或子目录仅能由拥有者或root用户来删除或重命名。比如/tmp目录中,如果所有用户都有读写权限,那么A进程在/tmp目录下创建的文件就有可能被B进程删除或移走。

❯ ls -ld /tmp
drwxrwxrwt 27 root root 36864  9月 19 12:49 /tmp

设置Sticky bit命令如下:

chmod o+t /tmp
chmod 1777 /sticky

可执行文件 #

标识了Sticky Bit的程序文件,在exec加载时,会将程序的代码段保存在交换分区中,以便加速下次启动的速度。Sticky Bit又称为saved-text bit。

setgid位

Content #

setgid位可用在目录或可执行文件上。

目录 #

若某目录设置了setgid位,则该目录下新创建的文件和子目录的拥有组将是该目录的拥有组,而不是创建该文件或目录的用户所属的组。被复制到这个目录下的文件或目录,也是一样,除非在cp命令中使用-p参数,来保留原来所属的组。

可执行文件 #

可执行文件设置了setgid位,则该文件拥有所属组的特权。

$ ls -l program1
-rwxr-xr-x 1 alex pubs 15828 Nov 5 06:28 program1
$ chmod g+s program1
$ ls -l program1
-rwxr-sr-x 1 alex pubs 15828 Nov 5 06:28 program1

From #

setuid位

setuid位

Content #

特殊权限setuid只能运用在可执行文件上,并且在设置setuid位以后,在可执行文件的拥有者权限中,原来的x变成了s,表示该文件在执行时将以文件所有者身份(一般会是root)访问系统。

$ ls -l program1
-rwxr-xr-x 1 alex pubs 15828 Nov 5 06:28 program1
$ chmod u+s program1
$ ls -l program1
-rwsr-xr-x 1 alex pubs 15828 Nov 5 06:28 program1

You can disable setuid programs at the filesystem level by mounting a filesystem with the nosuid option.

From #

align指令

Content #

在 GAS 汇编语言中,.align 指令用于将当前指令的地址对齐到指定边界。它的语法为:

.align <对齐位数>

对齐位数是一个正整数,表示对齐的边界值。当指令地址未对齐到该边界时,该指令会在当前地址后插入适当数量的空字节(通常是 0x00)以实现对齐效果。

当使用 .align 指令时,需要选择一个对齐位数来指定对齐的边界值。对齐位数通常是 2 的幂(例如 2、4、8、16 等),因为这样的对齐方式可以更高效地处理数据。

例如,如果我们使用 .align 4,它会将当前指令的地址对齐到 4 字节的边界。如果当前地址已经是 4 的倍数,则不会插入任何空字节。如果当前地址不是 4 的倍数,.align 4 会在当前地址后插入足够数量的空字节,直到地址对齐到 4 字节边界。

下面是一个示例:

``` .align 4 # 对齐到 4 字节边界 movl $1, %eax # 指令 1 .align 8 # 对齐到 8 字节边界 movl $2, %ebx # 指令 2 ```

在上面的示例中,第一个 .align 4 对齐到 4 字节边界。如果当前地址是 0x100,则不会添加任何空字节。第二个 .align 8 对齐到 8 字节边界。如果当前地址是 0x104,则需要在 0x104 和 0x108 之间插入 4 个空字节,以便对齐到 8 字节边界。

...

数组变量(Bash)

Content #

要为某个环境变量设置多个值,可以把值放在圆括号中,值与值之间以空格分隔:

$ mytest=(zero one two three four)

没什么特别的地方。如果想像普通环境变量那样显示数组,你会失望的:

$ echo $mytest
zero

以上代码只显示了数组的第一个值。要引用单个数组元素,必须使用表示其在数组中位置的索引。索引要写在方括号中,$符号之后的所有内容都要放入花括号中。

$ echo ${mytest[2]}
two

要显示整个数组变量,可以用通配符*作为索引:

$ echo ${mytest[*]}
zero one two three four

也可以改变某个索引位置上的值:

$ mytest[2]=seven
$ echo ${mytest[2]}
seven

甚至能用unset命令来删除数组中的某个值,但是要小心,这有点儿复杂。看下面的例子:

$ unset mytest[2]
$ echo ${mytest[*]}
zero one three four
$ echo ${mytest[2]}

$ echo ${mytest[3]}
three

这个例子用unset命令来删除索引2位置上的值。显示整个数组时,看起来好像其他索引已经填补了这个位置。但如果专门显示索引2位置上的值时,你会发现这个位置是空的。

可以在unset命令后跟上数组名来删除整个数组:

$ unset mytest
$ echo ${mytest[*]}

From #

Linux命令行与shell脚本编程大全

环境变量名何时使用$

Content #

在涉及环境变量名时,什么时候该使用\(,什么时候不该使用\),实在让人摸不着头脑。只需记住一点:

如果要用到(doing anything with)变量,就使用\(;如果要操作(doing anything to)变量,则不使用\)。

这条规则的一个例外是使用printenv显示某个变量的值。

From #

Linux命令行与shell脚本编程大全

env,printenv,set三个命令的区别

Content #

set命令既会显示全局和局部环境变量、用户自定义变量以及局部shell函数,还会按照字母顺序对结果进行排序。与set命令不同,env命令和printenv命令既不会对变量进行排序,也不会输出局部环境变量、局部用户自定义变量以及局部 shell函数。

env命令用于在给定环境下执行命令。它可以显示当前环境变量的值,也可以设置新的环境变量值并执行命令。例如,可以使用以下命令将环境变量VAR_NAME设置为value并执行command:

env VAR_NAME=value command

printenv命令只用于显示当前环境变量的值,而不执行任何命令。它不支持设置新的环境变量值。例如,可以使用以下命令显示VAR_NAME环境变量的值:

printenv VAR_NAME

From #

Linux命令行与shell脚本编程大全

临时文件的两种用法

Contents #

  1. 使用$$

    tmp_file="/tmp/tmp.$$"
    

    缺点是容易泄漏信息

  2. 使用mktemp

    tmp_file=$(mktemp) #创建临时文件
    [ -f "$tmp_file" ] && rm -f $tmp_file   #清除临时文件
    

From #

外部命令与内建命令

Content #

每当执行外部命令时,就会创建一个子进程。这种操作称为衍生(forking)。外部命令ps会显示其父进程以及自己所对应的衍生子进程:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
christi+  2367  2363  0 10:47 pts/0    00:00:00 -bash
christi+  4242  2367  0 13:48 pts/0    00:00:00 ps -f

作为外部命令,ps命令在执行时会产生一个子进程。在这里,ps命令的PID是 4242,父PID是2367。作为父进程的bash shell的PID是2367。

与外部命令不同,内建命令无须使用子进程来执行。内建命令已经和shell编译成一体,作为shell的组成部分存在,无须借助外部程序文件来执行。

From #

Linux命令行与shell脚本编程大全