There are almost no friends who are engaged in software development under linux who don't know the strings command. Let's take a look at man strings first:
strings - print the strings of printable characters in files.
It means, printable characters in the print file. Let me add, this file can be a text file (test.c), executable file (test), dynamic link library (test.o), static link library (test.a)
It's not my style to write a long story out of the code without actually verifying it. Let's do some code to order the dishes (the code is stored in test.c):
- #include <stdio.h>
- int add ( int x, int y)
- {
- return x + y;
- }
- int main ()
- {
- int a = 1;
- int b = 2;
- int c = add(a, b);
- printf("oh, my dear, c is %d\n", c);
- return 0;
- }
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int main()
{
int a = 1;
int b = 2;
int c = add(a, b);
printf("oh, my dear, c is %d\n", c);
return 0;
}
Let's take a look at the results of strings test.c:
- [taoge@localhost learn_c]$ strings test.c
- #include <stdio.h>
- int add (int x, int y)
- return x + y;
- int main ()
- int a = 1;
- int b = 2;
- int c = add(a, b);
- printf("oh, my dear, c is %d\n", c);
- return 0;
- [taoge@localhost learn_c]$
[taoge@localhost learn_c]$ strings test.c
#include <stdio.h>
int add(int x, int y)
return x + y;
int main()
int a = 1;
int b = 2;
int c = add(a, b);
printf("oh, my dear, c is %d\n", c);
return 0;
[taoge@localhost learn_c]$
As you can see, many characters in test.c are indeed printed.
Next, let's try using strings for executable files, as follows:
- [taoge@localhost learn_c]$ gcc test.c
- [taoge@localhost learn_c]$ strings a.out
- /lib/ld-linux.so.2
- = $ TsU
- __gmon_start__
- libc.so.6
- _IO_stdin_used
- printf
- __libc_start_main
- GLIBC_2.0
- PTRh
- [^_]
- oh, my dear, c is %d
- [taoge@localhost learn_c]$
[taoge@localhost learn_c]$ gcc test.c
[taoge@localhost learn_c]$ strings a.out
/lib/ld-linux.so.2
=$TsU
__gmon_start__
libc.so.6
_IO_stdin_used
printf
__libc_start_main
GLIBC_2.0
PTRh
[^_]
oh, my dear, c is %d
[taoge@localhost learn_c]$
As you can see, many characters in a.out are printed.
In fact, if there are object files, static libraries or dynamic libraries, you can also use the strings command to print. Let's take a look:
xxx.h file:
- void print();
void print();
xxx.c file:
- #include <stdio.h>
- #include "xxx.h"
- void print()
- {
- printf("rainy days\n");
- }
#include <stdio.h>
#include "xxx.h"
void print()
{
printf("rainy days\n");
}
Then, let's take a look at how to make static and dynamic libraries (will continue to introduce in detail in subsequent blog posts):
- [taoge@localhost learn_strings]$ ls
- xxx.c xxx.h
- [taoge@localhost learn_strings]$ gcc -c xxx.c
- [taoge@localhost learn_strings]$ ar rcs libxxx.a xxx.o
- [taoge@localhost learn_strings]$ gcc -shared -fPIC -o libxxx.so xxx.o
- [taoge@localhost learn_strings]$ ls
- libxxx.a libxxx.so xxx.c xxx.h xxx.o
- [taoge@localhost learn_strings]$ strings xxx.o
- rainy days
- [taoge@localhost learn_strings]$ strings libxxx.a
- !<arch>
- / 1437887339 0 0 0 14 `
- Rprint
- xxx.o/ 1437887333 501 502 100664 848 `
- rainy days
- GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)
- .symtab
- .strtab
- .shstrtab
- .rel.text
- .data
- .bss
- .rodata
- .comment
- .note.GNU-stack
- xxx.c
- puts
- [taoge@localhost learn_strings]$
- [taoge@localhost learn_strings]$
- [taoge@localhost learn_strings]$ strings libxxx.so
- __gmon_start__
- _init
- _fini
- __cxa_finalize
- _Jv_RegisterClasses
- puts
- libc.so.6
- _edata
- __bss_start
- _end
- GLIBC_2.1.3
- GLIBC_2.0
- rainy days
- [taoge@localhost learn_strings]$
[taoge@localhost learn_strings]$ ls
xxx.c xxx.h
[taoge@localhost learn_strings]$ gcc -c xxx.c
[taoge@localhost learn_strings]$ ar rcs libxxx.a xxx.o
[taoge@localhost learn_strings]$ gcc -shared -fPIC -o libxxx.so xxx.o
[taoge@localhost learn_strings]$ ls
libxxx.a libxxx.so xxx.c xxx.h xxx.o
[taoge@localhost learn_strings]$ strings xxx.o
rainy days
[taoge@localhost learn_strings]$ strings libxxx.a
!<arch>
/ 1437887339 0 0 0 14 `
Rprint
xxx.o/ 1437887333 501 502 100664 848 `
rainy days
GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)
.symtab
.strtab
.shstrtab
.rel.text
.data
.bss
.rodata
.comment
.note.GNU-stack
xxx.c
print
puts
[taoge@localhost learn_strings]$
[taoge@localhost learn_strings]$
[taoge@localhost learn_strings]$ strings libxxx.so
__gmon_start__
_init
_fini
__cxa_finalize
_Jv_RegisterClasses
print
puts
libc.so.6
_edata
__bss_start
_end
GLIBC_2.1.3
GLIBC_2.0
rainy days
[taoge@localhost learn_strings]$
See it.
The strings command is very simple and may seem like nothing, but it actually has many uses. Below, let me give an example. In large-scale software development, suppose there are 100 .c/.cpp files, this .cpp file finally generates 10 .so libraries, then how can we quickly know that a certain .c/.cpp file is compiled into which .so library Gone? Of course, you may have to say, you don’t know if you look at the makefile. Yes, it is certainly possible to look at the makefile, but the following method is better, just use the command directly:
strings -f "*.so" | grep "xxxxxx"
If you still don’t understand, just take the above applet as an example. However, here we consider all the files, as follows:
- [taoge@localhost learn_c]$ strings -f * | grep "my dear"
- a.out: oh, my dear, c is %d
- test.c: printf("oh, my dear, c is %d\n", c);
- [taoge@localhost learn_c]$
[taoge@localhost learn_c]$ strings -f * | grep "my dear"
a.out: oh, my dear, c is %d
test.c: printf("oh, my dear, c is %d\n", c);
[taoge@localhost learn_c]$
As you can see, there are "my dear" strings in both the source file test.c and the executable file, and the corresponding file was found all at once, is it clear. If a .c/.cpp file is compiled into the .so library, then strings -f * | grep "my dear" must be able to find the corresponding .so file, where "my dear" is in the .c/.cpp file A log string (for example, printf is used for printing).
The role of strings will be introduced first, so let's get familiar with strings.