strip 这个单词作为动词的时候有: “剥去;剥夺;脱去衣服”的意思
Python 中字符串对象提供了strip()
方法, 用于移除字符串头尾指定的字符(默认空格、制表符、换行符等)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符
- #!/usr/bin/python3
-
- str1 = "*****this is **string** example....wow!!!*****"
- print("str1: {}".format(str1.strip('*'))) # 在strip方法中指定需要移除的字符串
-
- str2 = " 123abcrunoob321\n"
- print("str2 orig: {0}; str2 new: {1}".format(str2, str2.strip())) # 在strip方法中不指定任何字符串
输出结果
- str1: this is **string** example....wow!!!
- str2 orig: 123abcrunoob321
- ; str2 new: 123abcrunoob321
从上面的结果中可以看到:
str1
中间的星号没有被移除掉, 证明了strip 方法确实只会移除掉字符串前后的指定内容str2
可以看到如果不指定参数,则会移除掉空格,换行符。先看man中的解释:
- NAME
- strip - discard symbols and other data from object files
-
- DESCRIPTION
- GNU strip discards all symbols from object files objfile.
- The list of object files may include archives.
- At least one object file must be given.
-
- strip modifies the files named in its argument, rather than writing modified copies under different names.
strip简单的说就是给文件剥掉外衣,具体就是从特定文件中剥掉一些符号信息和调试信息,使文件变小。
注意: 这里的文件必须是object files, 对于普通的文本文件没啥效果。
先看一个简单的C例子, 假设文件名称为strip_cmd.c
:
- [root@shiyan ~]# cat strip_cmd.c
- #include
-
- void main()
- {
- printf("this is strip cmd example! \n");
- }
用gcc编译该文件:
[root@shiyan ~]# gcc -o strip_cmd strip_cmd.c
使用ls命令来查看该文件大小,如下:
- [root@shiyan ~]# ll strip_c*
- -rwxr-xr-x 1 root root 8488 8月 5 17:25 strip_cmd
- -rw-r--r-- 1 root root 87 8月 5 17:24 strip_cmd.c
用file
命令来查看该文件结构,命令file strip_cmd
, 输出结果如下:
- [root@shiyan ~]# file strip_cmd
- strip_cmd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=fb9a4c8597aa494d78f4c7b11f5c9ab852820533, not stripped
注意最后面的not stripped
,说明没有被“剥去”
用nm
命令来查看该文件结构,命令nm strip_cmd
, 输出结果如下:
- [root@shiyan ~]# cat strip_cmd.c
- #include
-
- void main()
- {
- printf("this is strip cmd example! \n");
- }
- [root@shiyan ~]# nm strip_cmd
- 000000000060102c B __bss_start
- 000000000060102c b completed.6355
- 0000000000601028 D __data_start
- 0000000000601028 W data_start
- 0000000000400460 t deregister_tm_clones
- 00000000004004d0 t __do_global_dtors_aux
- 0000000000600e18 t __do_global_dtors_aux_fini_array_entry
- 00000000004005b8 R __dso_handle
- 0000000000600e28 d _DYNAMIC
- 000000000060102c D _edata
- 0000000000601030 B _end
- 00000000004005a4 T _fini
- 00000000004004f0 t frame_dummy
- 0000000000600e10 t __frame_dummy_init_array_entry
- 0000000000400700 r __FRAME_END__
- 0000000000601000 d _GLOBAL_OFFSET_TABLE_
- w __gmon_start__
- 00000000004005dc r __GNU_EH_FRAME_HDR
- 00000000004003c8 T _init
- 0000000000600e18 t __init_array_end
- 0000000000600e10 t __init_array_start
- 00000000004005b0 R _IO_stdin_used
- 0000000000600e20 d __JCR_END__
- 0000000000600e20 d __JCR_LIST__
- 00000000004005a0 T __libc_csu_fini
- 0000000000400530 T __libc_csu_init
- U __libc_start_main@@GLIBC_2.2.5
- 000000000040051d T main
- U puts@@GLIBC_2.2.5
- 0000000000400490 t register_tm_clones
- 0000000000400430 T _start
- 0000000000601030 D __TMC_END__
从上面的输出中,可以看到很多的符号
使用命令strip strip_cmd
来剥去这个文件的信息。
用ls
命令来查看该文件大小,如下:
- [root@shiyan ~]# strip strip_cmd
- [root@shiyan ~]# ll strip_c*
- -rwxr-xr-x 1 root root 6344 8月 5 17:32 strip_cmd
- -rw-r--r-- 1 root root 87 8月 5 17:24 strip_cmd.c
可以看到文件大小比原来的变小一些【原来是8488】
用file
命令来查看该文件结构,命令file strip_cmd
, 输出结果如下:
- [root@shiyan ~]# !f
- file strip_cmd
- strip_cmd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=fb9a4c8597aa494d78f4c7b11f5c9ab852820533, stripped
可以看到最后已经变成stripped
, 说明已经被“剥去”.
用nm
命令来查看该文件结构,命令nm strip_cmd
, 输出结果如下:
- [root@shiyan ~]# !n
- nm strip_cmd
- nm: strip_cmd:无符号
可以看到已经没有符号信息了。
由此可见, strip用于脱掉文件的衣服, 文件会变小, 其中的符号信息会失去。 那这个strip有什么用呢? 很有用的! 原来的strip_cmd
比较大, 可以执行。 在strip之后, 文件变小了, 仍然可以执行, 这就就节省了很多空间。
其实, strip不仅仅可以针对可执行文件, 还能针对目标文件和动态库等。
在实际的开发中, 经常需要对动态库.so进行strip操作, 减少占地空间。 而在调试的时候(比如用addr2line), 就需要符号了。 因此, 通常的做法是: strip前的库用来调试, strip后的库用来实际发布, 他们两者有对应关系。 一旦发布的strip后的库出了问题, 就可以找对应的未strip的库来定位。
最后啰嗦一句, 某某动态库strip前是18M左右, strip后是3M左右, 可见, 脱脱衣服还是有明显好处的。
补充: 后来发现, 在调试过程中, 经常涉及到传库, 库太大时, 很耗费传输时间, 所以还是用strip来搞一下吧。