updated
@@ -1,7 +1,7 @@
|
||||
[History]
|
||||
list=[["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4502,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",187,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",1701,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",187,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",877,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",944,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",125,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",2508,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",637,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",983,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",2995,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:personal.map",178,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4928,null]]
|
||||
list=[["Utils:gdb:gdb debugging",292,null],["Utils:gdb:gdb debugging:gdb pointer",284,null],["Utils:gdb:gdb debugging:gdb demo",340,null],["Research:Error Notes:\u4e0b\u8f7d\u9519\u8bef:chosen node create failed",0,null],["Programme:goagent",43,null],["Linux:accounts",0,null],["Utils:autoconf---automake",0,null],["Utils:autoconf---automake:\u4ee3\u7801",0,null],["Utils:blkid",0,null],["Utils:autoconf---automake",0,null],["Utils:gcc&g++",0,null],["Utils:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:gdb",0,null],["Utils:gcc&g++:Installing---GCC--Configuration",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",null,null]]
|
||||
current=24
|
||||
recent=[["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04",43,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:\u66f4\u6539\u952e\u76d8\u5e03\u5c40(vitual terminal\u548cX\u7a0b\u5e8f)",0,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:dumpkeys",75,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:dumpkeys -l",14500,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",2508,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",2995,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:personal.map",178,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4928,null]]
|
||||
recent=[["Utils:gdb",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",null,null]]
|
||||
|
||||
[MainWindow]
|
||||
windowsize=[1278,779]
|
||||
@@ -20,8 +20,8 @@ windowpos=[0,19]
|
||||
toolbar_style=None
|
||||
toolbar_size=tiny
|
||||
active_tabs=["Index",null,null,"Attachments"]
|
||||
toggle_panes=[]
|
||||
left_pane=[true,222,"Index"]
|
||||
toggle_panes=["left_pane"]
|
||||
left_pane=[true,276,"Index"]
|
||||
right_pane=[false,200,null]
|
||||
top_pane=[false,200,null]
|
||||
bottom_pane=[false,200,null]
|
||||
@@ -50,7 +50,7 @@ calendar_expanded=False
|
||||
[InsertImageDialog]
|
||||
windowsize=[1280,749]
|
||||
attach_inserted_images=False
|
||||
last_image_folder=/home/geekard/Notes/Zim/Research/\u5d4c\u5165\u5f0fPowerPC\u4e0a\u7684\u6241\u5e73\u8bbe\u5907\u6811FDT
|
||||
last_image_folder=/home/geekard/Notes/Zim/Utils/gdb/gdb_debugging
|
||||
|
||||
[InsertLinkDialog]
|
||||
windowsize=[328,156]
|
||||
@@ -70,7 +70,7 @@ windowsize=[637,165]
|
||||
windowsize=[500,400]
|
||||
|
||||
[PreferencesDialog]
|
||||
windowsize=[537,422]
|
||||
windowsize=[592,422]
|
||||
|
||||
[AttachmentBrowserPlugin]
|
||||
active=True
|
||||
@@ -125,5 +125,5 @@ output_file=/home/geekard/\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570
|
||||
windowsize=[411,157]
|
||||
|
||||
[FindAndReplaceDialog]
|
||||
windowsize=[330,298]
|
||||
windowsize=[332,298]
|
||||
|
||||
|
||||
129
Zim/.zim/state.conf.zim-new~
Normal file
@@ -0,0 +1,129 @@
|
||||
[History]
|
||||
list=[["Utils:gdb:gdb debugging:gdb demo",340,null],["Research:Error Notes:\u4e0b\u8f7d\u9519\u8bef:chosen node create failed",0,null],["Programme:goagent",43,null],["Linux:accounts",0,null],["Utils:autoconf---automake",0,null],["Utils:autoconf---automake:\u4ee3\u7801",0,null],["Utils:blkid",0,null],["Utils:autoconf---automake",0,null],["Utils:gcc&g++",0,null],["Utils:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:gdb",0,null],["Utils:gcc&g++:Installing---GCC--Configuration",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",null,null]]
|
||||
current=24
|
||||
recent=[["Utils:gdb",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",null,null]]
|
||||
|
||||
[MainWindow]
|
||||
windowsize=[1278,779]
|
||||
show_sidepane=True
|
||||
sidepane_pos=316
|
||||
show_menubar=True
|
||||
show_menubar_fullscreen=True
|
||||
show_toolbar=True
|
||||
show_toolbar_fullscreen=False
|
||||
show_statusbar=True
|
||||
show_statusbar_fullscreen=False
|
||||
pathbar_type=recent
|
||||
pathbar_type_fullscreen=none
|
||||
readonly=False
|
||||
windowpos=[0,19]
|
||||
toolbar_style=None
|
||||
toolbar_size=tiny
|
||||
active_tabs=["Index",null,null,"Attachments"]
|
||||
toggle_panes=["left_pane"]
|
||||
left_pane=[true,276,"Index"]
|
||||
right_pane=[false,200,null]
|
||||
top_pane=[false,200,null]
|
||||
bottom_pane=[false,200,null]
|
||||
|
||||
[ImportPageDialog]
|
||||
windowsize=[500,400]
|
||||
|
||||
[NewPageDialog]
|
||||
windowsize=[362,170]
|
||||
|
||||
[RenamePageDialog]
|
||||
windowsize=[643,204]
|
||||
|
||||
[DeletePageDialog]
|
||||
windowsize=[633,438]
|
||||
|
||||
[PropertiesDialog]
|
||||
windowsize=[395,299]
|
||||
|
||||
[InsertDateDialog]
|
||||
windowsize=[319,247]
|
||||
lastusedformat=%A %d/%m/%Y
|
||||
linkdate=True
|
||||
calendar_expanded=False
|
||||
|
||||
[InsertImageDialog]
|
||||
windowsize=[1280,749]
|
||||
attach_inserted_images=False
|
||||
last_image_folder=/home/geekard/Notes/Zim/Utils/gdb/gdb_debugging
|
||||
|
||||
[InsertLinkDialog]
|
||||
windowsize=[328,156]
|
||||
|
||||
[EditImageDialog]
|
||||
windowsize=[339,268]
|
||||
|
||||
[AttachFileDialog]
|
||||
windowsize=[500,400]
|
||||
last_attachment_folder=/home/geekard/Notes/Zim/Research/Error_Notes/\u7f16\u8bd1\u9519\u8bef/crdb
|
||||
insert_attached_images=False
|
||||
|
||||
[PromptExistingFileDialog]
|
||||
windowsize=[637,165]
|
||||
|
||||
[InsertTextFromFileDialog]
|
||||
windowsize=[500,400]
|
||||
|
||||
[PreferencesDialog]
|
||||
windowsize=[592,422]
|
||||
|
||||
[AttachmentBrowserPlugin]
|
||||
active=True
|
||||
bottompane_pos=516
|
||||
|
||||
[TaskListDialog]
|
||||
windowsize=[550,400]
|
||||
hpane_pos=75
|
||||
|
||||
[InsertSymbolDialog]
|
||||
windowsize=[350,400]
|
||||
|
||||
[InsertScreenshotDialog]
|
||||
windowsize=[212,148]
|
||||
|
||||
[WordCountDialog]
|
||||
windowsize=[316,146]
|
||||
|
||||
[CustomToolManagerDialog]
|
||||
windowsize=[410,299]
|
||||
|
||||
[OpenPageDialog]
|
||||
windowsize=[298,118]
|
||||
|
||||
[NotebookDialog]
|
||||
windowsize=[500,400]
|
||||
|
||||
[PageWindow]
|
||||
windowsize=[500,400]
|
||||
|
||||
[CalendarDialog]
|
||||
windowsize=[222,258]
|
||||
|
||||
[TagsPlugin]
|
||||
treeview=tagged
|
||||
tagcloud_sorting=score
|
||||
|
||||
[ExportDialog]
|
||||
windowsize=[400,325]
|
||||
document_root_url=
|
||||
selection=page
|
||||
selected_page=NonSQL:\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570\u636e\u5e93\uff1f
|
||||
format=HTML
|
||||
template=Default
|
||||
template_file=None
|
||||
document_root=absolute
|
||||
output_folder=None
|
||||
index_page=
|
||||
output_file=/home/geekard/\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570\u636e\u5e93\uff1f.html
|
||||
|
||||
[MovePageDialog]
|
||||
windowsize=[411,157]
|
||||
|
||||
[FindAndReplaceDialog]
|
||||
windowsize=[332,298]
|
||||
|
||||
11
Zim/Linux/accounts.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-02T14:03:59+08:00
|
||||
|
||||
====== accounts ======
|
||||
Created Friday 02 December 2011
|
||||
|
||||
kb310小熊
|
||||
ip: 192.168.1.113
|
||||
port: 222
|
||||
username: geekard
|
||||
@@ -1,14 +0,0 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-02T14:03:59+08:00
|
||||
|
||||
====== kb318 ======
|
||||
Created Friday 02 December 2011
|
||||
|
||||
常利伟帐号:
|
||||
ssh -p 1998 clw@192.168.1.1
|
||||
密码:000000
|
||||
|
||||
ssh 192.168.1.85
|
||||
root: 000000
|
||||
geekard:ho4o44
|
||||
@@ -8,3 +8,7 @@ Created Friday 02 November 2012
|
||||
grub: gfx = graphics, 两者的读音差不多。
|
||||
VESA = Video Electronics Standards Association
|
||||
VBE = VESA BIOS Extensions
|
||||
evdev = event device: A componet of the linux kernel for handling input(from keyboards, mice, joysticks, etc.)
|
||||
and a closely related input driver fo the X.Org server.The kernel componet is glue-code which translates input
|
||||
events from peripheral-specific drivers into a generic structure which the input driver can easily translate into X11
|
||||
events.
|
||||
|
||||
38
Zim/Programme/elf/Introduction_to_PIC.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-23T16:02:09+08:00
|
||||
|
||||
====== Introduction to PIC ======
|
||||
Created Sunday 23 December 2012
|
||||
http://www.gentoo.org/proj/en/hardened/pic-guide.xml
|
||||
|
||||
PIC code radically differs from conventional code in the way it calls functions and operates on data variables.
|
||||
It will access these functions and data __through an indirection table__, the "Global Offset Table" (GOT), by software convention accessible using the reserved name "**_GLOBAL_OFFSET_TABLE_**".
|
||||
|
||||
The exact mechanism used for this is hardware architecture dependent, but usually __a special machine register__ is reserved for setting up the location of the GOT when entering a function.
|
||||
|
||||
The rationale behind this indirect addressing is to generate code that can be __independently accessed__ of the actual load address. 例如共享库的目标代码在内存中只加载一次,但是可以映射到多个进程中。
|
||||
|
||||
In a true PIC library **without** relocations in the __text segment__, only the symbols exported in the __"Global Offset Table"__ need updating at run-time depending on the current load address of the various shared libraries in the address space of the running process. 使用PIC技术的共享库,在动态链接(映射)到某个进程的地址空间中时,其text section不需要重定位(更改),只需要对
|
||||
GOT表中的符号进行重定位即可。而GOT位于.data section中。
|
||||
|
||||
Likewise, procedure calls to globally defined functions are redirected through the __"Procedure Linkage Table" (PLT)__ residing in the data segment of the core image. Again, this is done to avoid run-time modifications to the text segment.
|
||||
其实PLT位于.text section之中,是只读和可执行的,它会使用GOT中的函数符号条目。
|
||||
|
||||
The __linker-editor__ allocates the Global Offset Table and Procedure Linkage Table when combining PIC object files into an image suitable for mapping into the process address space. It also collects all symbols that may be needed by the run-time link-editor and stores these along with the image's text and data bits. Another reserved symbol, **_DYNAMIC** is used to indicate the presence of the run-time linker structures. Whenever _DYNAMIC is relocated to 0, there is no need to invoke the run-time link- editor. If this symbol is non-zero, it points at a data structure from which the location of the necessary relocation- and symbol information can be derived. This is most notably used by the start-up module, **crt0, crt1S** and more recently **Scrt1**. The _DYNAMIC structure is conventionally located at the start of the data segment of the image to which it pertains.
|
||||
|
||||
On most architectures, when you compile source code to object code, you __need to specify__ whether the object code should be position independent or not. There are occasional architectures which don't make the distinction, usually because all object code is position independent by virtue of the __Application Binary Interface (ABI),__ or less often because the load address of the object is fixed at compile time, which implies that shared libraries are not supported by such a platform. If an object is compiled as position independent code (PIC), then the operating system can load the object __at any address__ in preparation for execution. This involves a time overhead, in replacing direct address references with relative addresses at compile time, and a space overhead, in maintaining information to help the runtime loader fill in the unresolved addresses at runtime.
|
||||
|
||||
Consequently, PIC objects are usually slightly larger and slower at runtime than the equivalent non-PIC object. The advantage of sharing library code on disk and in memory outweigh these problems as soon as the PIC object code in shared libraries is reused.
|
||||
|
||||
PIC compilation is exactly what is required for objects which will become __part of__ a shared library. Consequently, __libtool__ builds PIC objects for use in shared libraries and non-PIC objects for use in static libraries. Whenever libtool instructs the compiler to generate a PIC object, it also defines the preprocessor symbol, `PIC', so that assembly code can be aware of whether it will reside in a PIC object or not.
|
||||
|
||||
Typically, as libtool is compiling sources, it will generate a `.lo' object, as PIC, and a `.o' object, as non-PIC, and then it will use the appropriate one of the pair when linking executables and libraries of various sorts. On architectures where there is no distinction, the `.lo' file is just a soft link to the `.o' file.
|
||||
|
||||
In practice, you can link PIC objects into a static archive for a small overhead in execution and load speed, and often you can similarly link non-PIC objects into shared archives.
|
||||
|
||||
When you use position-independent code, relocatable references are generated as an indirection that use data in the shared object's data segment. The text segment code remains read-only, and all relocation updates are applied to corresponding entries within the data segment.
|
||||
|
||||
If a shared object is built from code that is not position-independent, the text segment will usually require a large number of relocations to be performed at runtime. Although the runtime linker is equipped to handle this, the system overhead this creates can cause serious performance degradation.
|
||||
|
||||
You can identify a shared object that requires relocations against its text segment using tools such as 'readelf -d foo' and inspect the output for any TEXTREL entry. The value of the TEXTREL entry is irrelevant. Its presence in a shared object indicates that text relocations exist.
|
||||
213
Zim/Programme/elf/elf_重定位.txt
Normal file
@@ -0,0 +1,213 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-21T20:33:28+08:00
|
||||
|
||||
====== elf 重定位 ======
|
||||
Created Friday 21 December 2012
|
||||
|
||||
Relocation is the process of __associate the symbolic reference with symbolic definition.__ For example, when a program calls a function, the associate all instruction must transfor control to the **proper destination address.** In other words, relocatable files must have information for modifying their section content.
|
||||
|
||||
Relocation table entry structer:
|
||||
{{./0.gif}}
|
||||
|
||||
* **r_offset:** Holds the location at which the relocation apply. For a relocable file, the value is the byte offset from the beginning of the section to the storage unit affected by relocation. For an executable file or a share object file, the value is the virtual address of units affected by relocation.
|
||||
* **r_info:** Holds both the __symbol table index__ with respect to which the relocation must be made, and __the type of relocation__. For example, a call instrution's relocation enry would hold the symbol index of the function. Relocation types are processor-sepcific. The following code shows how to manipulate the values.
|
||||
#define ELF32_R_SYM(info) ((info)>>8)
|
||||
#define ELF32_R_TYPE(info) ((info)&ff)
|
||||
#define ELF32_R_INFO(s,t) (((s)<<8) + ((t)&0xff))
|
||||
symbol: bits 32–8
|
||||
type: bits 7–0
|
||||
**r_addend:** Holds a constand addend used to compute the value to be stored into the relocable field.
|
||||
|
||||
===== Relocation Types:(SYSTEM V Architecture) =====
|
||||
The __link editor__ merge one or more relocable object files to form the output. It first disides how to combine and locate the input files then update the symbol values, and finally preform the relocation. Relocations applied to excutable or shared object files are similar.
|
||||
|
||||
link editor(ld)首先合并可重定位目标文件,然后解析其中的符号引用,并将符号的最终实际地址写入到符号表中,最后重定位。
|
||||
|
||||
The relocation types specific which bits to change and how to caculate their values(下表真对的是x86而非x86_64).
|
||||
{{./1.gif}}
|
||||
|
||||
**R_386_32:** Symbol’s value + addend. In the following Fig, thre is a relocation at the **0×7 bytes** offset into **.text** section. The linker alter the address of ‘b’ with S+A, S is symbold b’s new address after reset. A is the endian, here it is zero.
|
||||
**R_386_32是绝对寻址的重定位。将符号解析后的绝对实际地址填充到关联section的offset处。**
|
||||
{{./2.gif}}
|
||||
**R_386_PC32:** Symbol’s **value+Addend-Place**. Because it is __Relative Near CALL__, the operand is the offset from the “next instruction” (EIP) to the called procedure, more infor is here. **VALUE+EIP = Symbol.value, EIP = Place+4. So VALUE = Symbold.value – 4 – Place**. S is ‘Symbol.vale’, ‘-4′ is the Addend. P is the new virtuall address of relocation entry computed by r_offset and other factors.
|
||||
R_386_PC32是相对寻址的重定位。S是符号表中符号解析后的实际地址,Place是调用该符号的指令地址,所以相对偏移量为 **VALUE = Symbold.value – 4 – Place**
|
||||
|
||||
**R_386_GLOB_DAT:** This type is used to __set a global offset table entry__ to the address of the specific symbol. It is used for global or external variable in PIC code . 将解析后的全局或外部符号的实际地址写入到对应的__GOT条目中__。
|
||||
|
||||
**R_386_JMP_SLOT:** The linker editor creates this relocation type for dynamic linking. Its offset specify __the GOT entry that contain a PLT entry__. The dynamic linker use it to implement lazy linking.将解析后的外部函数实际入口地址写入到对应的GOT中的PLT条目类型中。
|
||||
|
||||
R_386_GLOB_DAT and R_386_JMP_SLOT are only appear in executable file or shared library.
|
||||
|
||||
__上面两种类型的重定位是由动态链接器解析符号后完成的,与代码里是否引用该符号无关(因为代码是间接地利用GOT,PLT来引用外部变量和符号的)。而且是对GOT中的符号value进行填充,与代码段无关。__
|
||||
|
||||
**R_386_GOTOFF:**引用本文件内使用的static和rodata类型变量时使用的重定位类型。外部static变量和函数内static变量定义在.data section中,对它们的引用不通过GOT条目,而是其符号位置与GOT首地址的偏移量来实现的(同理,字符串字面量由于不能修改,一般保存在.rodata section中,对它们的引用也不是通过GOT条目),即重定位值= S+A-GOT。示例如下:
|
||||
//ebx事先保存的是GOT的首地址
|
||||
movl __globalVarStatic@GOTOFF__(%ebx), %eax __//globalVarStatic@GOTOFF的值为S+A-GOT,再加上GOT的正好为符号globalVarStatic的地址。__
|
||||
movl (%eax), 4(%esp)
|
||||
|
||||
**R_386_GOT32:**代码中引用外部变量时,ld生成的重定位类型。动态链接器将G+A-P的值填充到代码中的重定位位置。所以CPU实际寻址时得到的地址为R_386_GOT32+P-A = G。
|
||||
**R_386_PLT32:**代码中引用外部函数时,ld生成的重定位类型。动态链接器将L+A-P的值填充到代码中的重定位位置。所以CPU实际寻址时得到的地址为R_386_PLT32+P-A = L。
|
||||
|
||||
上面的G和L指的是__相应符号GOT条目距GOT首地址的偏移量。注意GOT32和PLT32一般和GOTPC一起使用,后者将GOT的首地址填充到代码段中的引用位置处。G+GOTPC=相应符号在GOT条目中的实际地址。__
|
||||
|
||||
在代码中引用外部变量时,汇编器一般生成如下代码(x86系统,如果是x86_64则直接具有**rip寄存器**):
|
||||
call __i686.get_pc_thunk.cx
|
||||
addl $_GLOBAL_OFFSET_TABLE_, %ecx //_GLOBAL_OFFSET_TABLE符号的值是__GOT表首地址距当前指令的偏移量__,它的重定位类型为R_386_GOTPC。现在ecx寄存器保存的是__GOT表的绝对地址__。
|
||||
movl var@GOT(%ecx), %eax //var@GOT是__var符号在GOT表中的偏移量__,所以var@GOT(%ecx)会通过GOT中的var条目取得__var符号的实际地址,并将其保存在eax寄存器中__。var@GOT的值是通过R_386_GOT32重定位的。
|
||||
movl (%eax), %eax //取得var符号引用的内存单元值,保存到eax寄存器中。
|
||||
__i686.get_pc_thunk.cx: //该函数的目的是获取EIP的值。
|
||||
mov (%esp),%ecx //此时的esp指向的内存单元保存的值时__函数返回后执行的指令地址,即紧接着call的addl指令地址__。
|
||||
ret
|
||||
|
||||
**R_386_GOTPC:** This type asembles R_386_PC32, except it use __the address of GOT__ in its caculation. The symbol referenced in this relocation normally is **_GLOBAL_OFFSET_TABLE_(见上面的代码示例)** , which additionally instructs linker to build the GOT. It normally used in PIC’s relocable files. See “ELF PIC Dessection“.
|
||||
|
||||
Sample:
|
||||
d.c
|
||||
int var = 10;
|
||||
void fun (void){
|
||||
var++;
|
||||
int a = var;
|
||||
}
|
||||
#gcc -S -o __d.s__ -fPIC d.c //生成汇编代码,这样其中包含有__编译器生成的指导汇编器生成重定位条目的具体信息__。而通过objdump -d d.o看到的反汇编代码已经去掉了这些重定位信息。
|
||||
#gcc -c -o d.o -fPIC d.c
|
||||
In d.s, d.c assembled with PIC option, there are instructions to load the GOT address, shown in the following figure.
|
||||
{{./3.gif}}
|
||||
|
||||
There will be a R_386_GOTPC relocation entry in d.o for __update the value of “$_GLOBAL_OFFSET_TABLE”__ to the offset from “addl” to “GOT”(addl指令的地址与GOT表首地址的差值即为_GLOBAL_OFFSET_TABLE符号的值。__该值的计算方法是由重定位类型决定的__), see the following figure(objdump -d的反汇编代码已经看不出原始的重定位信息). The relocation entry is at 0xd bytes offset from .text section, $_GLOBAL_OFFSET_TABLE resides there. The item’s initial value is ’0×2′. It is the endian A for caculating the address of ‘addl’. During the relocation, the linker caculate the relocation entry’s P (position) by r_offset first. Thus P-2 is the address ‘addl’. why -2? because the opcode of ‘addl’ is 2 bytes long. So $_GLOBAL_OFFSET_TABLE = GOT-P+A.
|
||||
{{./4.gif}}
|
||||
|
||||
**R_386_COPY:** The link editor creates this relocation type for dynamic linking. Its offset member refers to a location in a writable segement. The symbol table index specifies a symbol that should exists __both__ in the current object file and in a shared object. During execution, the dynamic linker __copies the data__ associated with the shared object’s symbol to location specified by the offset.
|
||||
|
||||
Sample:
|
||||
|
||||
[root@www save]# cat 386copy.c
|
||||
#include <stdio.h>
|
||||
extern int a;
|
||||
int main(void) {
|
||||
printf(“%d\n”, a);
|
||||
}
|
||||
[root@www save]# cat b.c
|
||||
int a = 10;
|
||||
|
||||
#gcc -fPIC -share -o b.so b.c
|
||||
#gcc -o 386copy 386copy.c ./b.so
|
||||
|
||||
{{./5.gif}}
|
||||
Fig2 shows the variable a’s value from shared object to executable’s .bss section.
|
||||
|
||||
===== Notation: =====
|
||||
S : The value of the symbol whose index resides in the relocation entry’s r_info.
|
||||
A: The addend used to caculate the value of the relocation field.
|
||||
P: The place, section offset or address, of the storage unit __being relocated__ (computed useing r_offset).__也就是计算后的值所替换的位置。__
|
||||
G: The __offset__ into the global offset table at which the address of relocation entry’s symbol will reside during execution.
|
||||
GOT: The address of the global offset table.
|
||||
L: The place, section offset or address, of PLT entry for a symbol.
|
||||
B: The __base address__ at which a shared object file has been loaded into the memory during execution.
|
||||
|
||||
|
||||
===== Relocation section: =====
|
||||
A relocation section(**而不是重定位条目的属性**) reference other two sections: __a symbol table and a section to modify__. The section header’s sh_info and sh_link, specify these relationships. sh_link is the symbol table index, sh_info is the section link.
|
||||
|
||||
Samples Code:
|
||||
|
||||
#include <stdio.h>
|
||||
char a = ‘a’;
|
||||
int b = 10;
|
||||
extern char c;
|
||||
extern void fun();
|
||||
void pp (void) { }
|
||||
|
||||
int main(void) {
|
||||
printf(“%d\n”, __b__);
|
||||
int bb = __b__;
|
||||
char cc = __c__; //b和c都是绝对寻址
|
||||
**pp**(); //相对寻址
|
||||
fun();
|
||||
}
|
||||
|
||||
# gcc -c -o test1 test.c //生成的是可重定位的目标对象文件,__没有使用GOT和PLT__,所以和它们相关的重定位类型都没有使用。一般只使用了__R_386_PC32和R_386_32__两种类型。
|
||||
[geekard@geekard rel]$ readelf -r rel.o
|
||||
|
||||
Relocation section '.rel.text' at offset 0x478 contains 7 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
0000000f 00000a01 __R_386_32__ 00000004 b
|
||||
0000001a 00000501 R_386_32 00000000 .rodata
|
||||
0000001f 00000d02 R_386_PC32 00000000 printf
|
||||
00000024 00000a01 R_386_32 00000004 b
|
||||
0000002f 00000e01 R_386_32 00000000 c
|
||||
00000038 00000b02 R_386_PC32 00000000 pp
|
||||
0000003d 00000f02 __R_386_PC32__ 00000000 fun
|
||||
|
||||
Relocation section '.rel.eh_frame' at offset 0x4b0 contains 2 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000020 00000202 R_386_PC32 00000000 .text
|
||||
00000040 00000202 R_386_PC32 00000000 .text
|
||||
|
||||
没有使用PIC技术时,对目标对象文件中全局变量符号引用地址的重定位是直接用实际地址替换(**R_386_32**),对__内部和外部函数__的调用是相对调转(**R_386_PC32**)。
|
||||
[geekard@geekard rel]$ readelf -s rel.o
|
||||
|
||||
Symbol table '.symtab' contains 16 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 00000000 0 FILE LOCAL DEFAULT ABS rel.c
|
||||
2: 00000000 0 SECTION LOCAL DEFAULT 1
|
||||
3: 00000000 0 SECTION LOCAL DEFAULT 3
|
||||
4: 00000000 0 SECTION LOCAL DEFAULT 4
|
||||
5: 00000000 0 SECTION LOCAL DEFAULT 5
|
||||
6: 00000000 0 SECTION LOCAL DEFAULT 7
|
||||
7: 00000000 0 SECTION LOCAL DEFAULT 8
|
||||
8: 00000000 0 SECTION LOCAL DEFAULT 6
|
||||
**9: 00000000 1 OBJECT GLOBAL DEFAULT 3 a**
|
||||
** 10: 00000004 4 OBJECT GLOBAL DEFAULT 3 b**
|
||||
** 11: 00000000 5 FUNC GLOBAL DEFAULT 1 pp**
|
||||
** 12: 00000005 62 FUNC GLOBAL DEFAULT 1 main**
|
||||
** 13: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf**
|
||||
** 14: 00000000 0 NOTYPE GLOBAL DEFAULT UND c**
|
||||
** 15: 00000000 0 NOTYPE GLOBAL DEFAULT UND fun**
|
||||
[geekard@geekard rel]$
|
||||
[geekard@geekard rel]$ gcc -c __-fPIC__ -o rel.o rel.c #还是可重定位目标类型目标文件,但是符号的引用使用了__位置无关__技术,所以对全局变量和外部函数的引用使用了GOT和PLT。
|
||||
[geekard@geekard rel]$ readelf -r rel.o
|
||||
|
||||
Relocation section '.rel.text' at offset 0x594 contains 9 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000010 00000f02 R_386_PC32 00000000 __x86.get_pc_thunk.bx
|
||||
00000016 0000100a __R_386_GOTPC__ 00000000 _GLOBAL_OFFSET_TABLE_
|
||||
0000001c 00000c03 __R_386_GOT32__ 00000004 b
|
||||
00000028 00000509 R_386_GOTOFF 00000000 .rodata
|
||||
00000030 00001104 R_386_PLT32 00000000 printf
|
||||
00000036 00000c03 R_386_GOT32 00000004 b
|
||||
00000042 00001203 R_386_GOT32 00000000 c
|
||||
0000004e 00000d04 __R_386_PLT32__ 00000000 pp
|
||||
00000053 00001304 R_386_PLT32 00000000 fun
|
||||
|
||||
Relocation section '.rel.eh_frame' at offset 0x5dc contains 3 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000020 00000202 R_386_PC32 00000000 .text
|
||||
00000040 00000202 R_386_PC32 00000000 .text
|
||||
00000064 00000602 R_386_PC32 00000000 .text.__x86.get_pc_thu
|
||||
[geekard@geekard rel]$
|
||||
使用了PIC技术后,所有符号的重定位使用__GOT和PLT。__
|
||||
|
||||
Here is the details of how REL section associated with symbol table and the section to relocation.
|
||||
|
||||
1. Show the ELF sections.
|
||||
{{./7.gif}}
|
||||
|
||||
In fig1, the section ‘.rel.text’ is ‘REL’, the sections it is associated with are the first and the 9th section, ‘.text’ and ‘.symtab’.
|
||||
|
||||
2. Show the relocation section entries:
|
||||
{{./8.gif}}
|
||||
In fig2, we can see there are two relocation entries for symbol ‘b’ because ‘b’ is referenced two times and the linker has to relocation it two times.
|
||||
|
||||
3. What is the raw data of relocation table entry?
|
||||
{{./9.gif}}
|
||||
|
||||
Fig3 shows the content of the first entry of relocation table. r_offset is 0×10, that means the relocation entry is at the 0×10 of test1. the symbol table index is 0×09. we can see the 9th entry of symbol table is ‘b’ through Fig4;
|
||||
|
||||
4. b’s offset if 4 byts offset from the start of data section and size is 4 bytes. Then the linercaculate the address of b and modify it’s address in .text section through relocation entry.
|
||||
{{./10.gif}}
|
||||
|
||||
So, we get a simple flow of how linker do the relocation. __first, get all relocation entries, then get all symbols associated with the relocation entries, then caculate the address and modify the unist in the section assosicated with the relocation entries.__ The real relocation is more complex but main flow is like this.
|
||||
|
||||
Sunday, September 12th, 2010 at 16:29
|
||||
BIN
Zim/Programme/elf/elf_重定位/0.gif
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
Zim/Programme/elf/elf_重定位/1.gif
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
Zim/Programme/elf/elf_重定位/10.gif
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
Zim/Programme/elf/elf_重定位/2.gif
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Zim/Programme/elf/elf_重定位/3.gif
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
Zim/Programme/elf/elf_重定位/4.gif
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Zim/Programme/elf/elf_重定位/5.gif
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Zim/Programme/elf/elf_重定位/6.gif
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
Zim/Programme/elf/elf_重定位/7.gif
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
Zim/Programme/elf/elf_重定位/8.gif
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
Zim/Programme/elf/elf_重定位/9.gif
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
15
Zim/Programme/elf/elf_重定位/CFI_for_gas.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-23T13:11:25+08:00
|
||||
|
||||
====== CFI for gas ======
|
||||
Created Sunday 23 December 2012
|
||||
|
||||
Modern ABIs don't require frame pointers to be used in functions.
|
||||
Howerver missing FPs bring difficulties when doing a backtrace.
|
||||
One solutions is to provide Dwarf-2 CFI(call frame information) data
|
||||
for each such function. This can be easily done for example by GCC in
|
||||
its output, but isn't that easy to write by hand for pure assembler functions.
|
||||
|
||||
With the help of these .cfi_* directives one can ass appropriate unwind info
|
||||
into his asm source without too much trouble.
|
||||
198
Zim/Programme/elf/elf_重定位/sample2--可重定位类型.txt
Normal file
@@ -0,0 +1,198 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-22T10:50:43+08:00
|
||||
|
||||
====== sample2--可重定位类型 ======
|
||||
Created Saturday 22 December 2012
|
||||
[geekard@geekard rel]$ cat -n rel.c **#测试文件**
|
||||
1 #include <stdio.h>
|
||||
2 int globalVar = 1;
|
||||
3 int globalVarUninit;
|
||||
4 static int globalVarStatic = 3;
|
||||
5 extern externVar;
|
||||
6
|
||||
7 extern void externFun(void);
|
||||
8 void Fun(void) {}
|
||||
9
|
||||
10 int main(void) {
|
||||
11 int autoVar = globalVar;
|
||||
12 static int staticVar = 2;
|
||||
13 globalVarUninit = externVar;
|
||||
14 printf("%d\n",globalVarStatic);
|
||||
15 externFun();
|
||||
16 Fun();
|
||||
17 }
|
||||
[geekard@geekard rel]$ **gcc -c rel.c #编译,生成可重定位类型的目标对象文件**
|
||||
[geekard@geekard rel]$ readelf **-r** rel.o **#查看可重定位条目**
|
||||
|
||||
Relocation section '.rel.text' at offset 0x4e0 contains 8 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
0000000f 00000b01 R_386_32 00000000 globalVar __#对文件中的第11行变量引用进行重定位__
|
||||
00000018 00000f01 R_386_32 00000000 externVar **#13**
|
||||
0000001d 00000c01 R_386_32 00000004 globalVarUninit **#13**
|
||||
00000022 00000301 R_386_32 00000000 .data
|
||||
0000002d 00000601 R_386_32 00000000 .rodata
|
||||
00000032 00001002 R_386_PC32 00000000 printf **#14**
|
||||
00000037 00001102 R_386_PC32 00000000 externFun **#15**
|
||||
0000003c 00000d02 R_386_PC32 00000000 Fun **#16**
|
||||
|
||||
Relocation section '.rel.eh_frame' at offset 0x520 contains 2 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000020 00000202 R_386_PC32 00000000 .text
|
||||
00000040 00000202 R_386_PC32 00000000 .text
|
||||
由于在编译时没有指定PIC,所以重定位条目没有使用GOT或PLT。对全局变量使用的时R_386_32的绝对地址重定位,对函数使用的是
|
||||
R_386_PC32相对寻址重定位。
|
||||
|
||||
[geekard@geekard rel]$ **objdump -t rel.o #查看符号表**
|
||||
|
||||
rel.o: file format elf32-i386
|
||||
|
||||
SYMBOL TABLE:
|
||||
00000000 l df *ABS* 00000000 rel.c
|
||||
00000000 l d .text 00000000 .text
|
||||
00000000 l d .data 00000000 .data
|
||||
00000000 l d .bss 00000000 .bss
|
||||
00000004 l O __.data__ 00000004 globalVarStatic
|
||||
00000000 l d .rodata 00000000 .rodata
|
||||
00000008 l O __.data__ 00000004 staticVar.1828
|
||||
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
|
||||
00000000 l d .eh_frame 00000000 .eh_frame
|
||||
00000000 l d .comment 00000000 .comment
|
||||
00000000 g O __.data__ 00000004 globalVar
|
||||
00000004 O __*COM*__ 00000004 globalVarUninit
|
||||
00000000 g F .text 00000005 Fun
|
||||
00000005 g F .text 0000003d main
|
||||
00000000 *UND* 00000000 externVar
|
||||
00000000 *UND* 00000000 printf
|
||||
00000000 *UND* 00000000 externFun
|
||||
[geekard@geekard rel]$
|
||||
全局静态变量、全局已初始化变量、静态自动变量都位于.data section中。但是全局未初始化变量位于COMMON(named after Fortran 77's "common blocks") section中,而且对外不可见。file-scope and local-scope uninitiated global variables 保存在bss("Block Started by Symbol")段中。如果想让globalVarUninit保存在.bss section中,可以在编译时使用-fno-common选项,则是建议的用法。
|
||||
geekard@ubuntu:~/Code$ cat bar.c
|
||||
double globalVar;
|
||||
int main() {}
|
||||
geekard@ubuntu:~/Code$ cat bar.c
|
||||
double globalVar;
|
||||
int main() {}
|
||||
geekard@ubuntu:~/Code$
|
||||
geekard@ubuntu:~/Code$ gcc foo.c bar.c
|
||||
编译并链接上面两个文件时,编译器并没有提示符号重复定义的错误,但是如果启用-fno-common选项,则会提示错误。
|
||||
geekard@ubuntu:~/Code$ gcc foo.c bar.c **-fno-common**
|
||||
/tmp/cceNAIis.o:(.bss+0x0): multiple definition of `globalVar'
|
||||
/tmp/ccWmFhZG.o:(.bss+0x0): first defined here
|
||||
/usr/bin/ld: Warning: size of symbol `globalVar' changed from 4 in /tmp/ccWmFhZG.o to 8 in /tmp/cceNAIis.o
|
||||
collect2: ld 返回 1
|
||||
geekard@ubuntu:~/Code$
|
||||
则是由于foo.oh和bar.o中的globalVar都放在.bss section中,而且都是global bind,所以会冲突。注意,放在COMMON section中时
|
||||
没有bind属性,默认是外界不可见的:
|
||||
geekard@ubuntu:~/Code$ objdump -t bar.o |grep globalVar //未启用-fno-common,无绑定信息,外界不可见
|
||||
0000000000000008 __O *COM*__ 0000000000000008 globalVar
|
||||
geekard@ubuntu:~/Code$ objdump -t bar.o |grep globalVar //启用-fno-common后
|
||||
0000000000000000 __g__ O __.bss__ 0000000000000008 globalVar
|
||||
kkkn
|
||||
[geekard@geekard rel]$ __gcc -S rel.c #编译__
|
||||
[geekard@geekard rel]$ cat rel.s #查看编译生成的汇编代码,代码中含有指示链接器ld生成各section和重定位的指令。
|
||||
.file "rel.c"
|
||||
.globl globalVar **#符号全局可见**
|
||||
.data **#data section开始**
|
||||
.align 4
|
||||
.type globalVar, @object **#符号类型**
|
||||
.size globalVar, 4 **#符号对象大小**
|
||||
globalVar:
|
||||
.long 1 **#符号的值**
|
||||
__.comm__ globalVarUninit,4,4 **#COMMON section**
|
||||
.align 4
|
||||
.type globalVarStatic, @object
|
||||
.size globalVarStatic, 4
|
||||
globalVarStatic:
|
||||
.long 3
|
||||
.text **#代码段开始**
|
||||
.globl Fun
|
||||
.type Fun, @function
|
||||
Fun:
|
||||
.LFB0:
|
||||
.cfi_startproc
|
||||
pushl %ebp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset 5, -8
|
||||
movl %esp, %ebp
|
||||
.cfi_def_cfa_register 5
|
||||
popl %ebp
|
||||
.cfi_restore 5
|
||||
.cfi_def_cfa 4, 4
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size Fun, .-Fun #函数对象的大小
|
||||
.section .rodata **#rodata section的开始**
|
||||
.LC0:
|
||||
.string "%d\n"
|
||||
.text
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB1:
|
||||
.cfi_startproc
|
||||
pushl %ebp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset 5, -8
|
||||
movl %esp, %ebp
|
||||
.cfi_def_cfa_register 5
|
||||
andl $-16, %esp
|
||||
subl $32, %esp
|
||||
movl __globalVar,__ %eax __#对全局变量的引用是绝对寻址,没有使用GOT。汇编时as会生成R_386_32类型的重定位条目__
|
||||
movl %eax, 28(%esp)
|
||||
movl __externVar__, %eax
|
||||
movl %eax, __globalVarUninit__
|
||||
movl __globalVarStatic__, %eax
|
||||
movl %eax, 4(%esp)
|
||||
movl $.LC0, (%esp)
|
||||
call __printf #对外部或全局函数的引用,使用的是相对寻址,没有使用PLT。汇编时as会生成R_386_PC32类型的重定位条目__
|
||||
call __externFun__
|
||||
call __Fun __
|
||||
leave
|
||||
.cfi_restore 5
|
||||
.cfi_def_cfa 4, 4
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size main, .-main
|
||||
.data
|
||||
.align 4
|
||||
.type __staticVar.1828__, @object
|
||||
.size staticVar.1828, 4
|
||||
staticVar.1828:
|
||||
.long 2
|
||||
.ident "GCC: (GNU) 4.7.2"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
[geekard@geekard rel]$
|
||||
[geekard@geekard rel]$ objdump -d rel.o
|
||||
|
||||
rel.o: file format elf32-i386
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <Fun>:
|
||||
0: 55 push %ebp
|
||||
1: 89 e5 mov %esp,%ebp
|
||||
3: 5d pop %ebp
|
||||
4: c3 ret
|
||||
|
||||
00000005 <main>:
|
||||
5: 55 push %ebp
|
||||
6: 89 e5 mov %esp,%ebp
|
||||
8: 83 e4 f0 and $0xfffffff0,%esp
|
||||
b: 83 ec 20 sub $0x20,%esp
|
||||
e: a1 00 00 00 00 mov 0x0,%eax
|
||||
13: 89 44 24 1c mov %eax,0x1c(%esp)
|
||||
17: a1 00 00 00 00 mov 0x0,%eax
|
||||
1c: a3 00 00 00 00 mov %eax,0x0
|
||||
21: a1 04 00 00 00 mov 0x4,%eax
|
||||
26: 89 44 24 04 mov %eax,0x4(%esp)
|
||||
2a: c7 04 24 00 00 00 00 movl $0x0,(%esp)
|
||||
31: e8 fc ff ff ff call 32 <main+0x2d>
|
||||
36: e8 fc ff ff ff call 37 <main+0x32>
|
||||
3b: e8 fc ff ff ff call 3c <main+0x37>
|
||||
40: c9 leave
|
||||
41: c3 ret
|
||||
[geekard@geekard rel]$
|
||||
236
Zim/Programme/elf/elf_重定位/sample3--PIC可重定位类型.txt
Normal file
@@ -0,0 +1,236 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-22T22:55:46+08:00
|
||||
|
||||
====== sample3--PIC可重定位类型 ======
|
||||
Created Saturday 22 December 2012
|
||||
|
||||
[geekard@geekard rel]$ cat rel.c
|
||||
#include <stdio.h>
|
||||
int globalVar = 1;
|
||||
int globalVarUninit;
|
||||
static int globalVarStatic = 3;
|
||||
extern externVar;
|
||||
|
||||
extern void externFun(int);
|
||||
void Fun(void) {}
|
||||
|
||||
int main(void) {
|
||||
int autoVar = globalVar;
|
||||
static int staticVar = 2;
|
||||
globalVarUninit = externVar;
|
||||
printf("%d\n",globalVarStatic);
|
||||
externFun(staticVar);
|
||||
Fun();
|
||||
}
|
||||
[geekard@geekard rel]$ gcc -c __-fPIC__ rel.c
|
||||
[geekard@geekard rel]$ readelf -r rel.o
|
||||
|
||||
Relocation section '**.rel.text**' at offset 0x600 contains 10 entries: **//对text section中的符号引用重定位**
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000010 00001102 R_386_PC32 00000000 __x86.get_pc_thunk.bx //相对寻址重定位,这里没有使用PLT是因为该函数是文件内部定义的。
|
||||
00000016 0000120a R_386___GOTPC__ 00000000 _GLOBAL_OFFSET_TABLE_ //用IP与GOT首地址的偏移量重定位代码中的值。
|
||||
0000001c 00000d03 R_386___GOT32__ 00000000 globalVar //用var条目在GOT中的偏移量重定位代码中的值。
|
||||
00000028 00001303 R_386_GOT32 00000000 externVar
|
||||
00000030 00000e03 R_386_GOT32 00000004 globalVarUninit
|
||||
00000038 00000309 R_386___GOTOFF__ 00000000 .data //用__static符号的地址与GOT的偏移量__来重定位代码段中的值。
|
||||
00000042 00000609 R_386_GOTOFF 00000000 .rodata //.rodata section中保存的是**字符串字面量**。
|
||||
0000004a 00001404 R_386___PLT32__ 00000000 printf //用printf条目在GOT PLT中的偏移量重定位代码中的值。
|
||||
00000050 00000309 R_386_GOTOFF 00000000 .data
|
||||
0000004f 00001504 R_386_PLT32 00000000 externFun
|
||||
00000054 00000f04 R_386_PLT32 00000000 Fun
|
||||
|
||||
Relocation section '.rel.eh_frame' at offset 0x650 contains 3 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000020 00000202 R_386_PC32 00000000 .text
|
||||
00000040 00000202 R_386_PC32 00000000 .text
|
||||
00000064 00000802 R_386_PC32 00000000 .text.__x86.get_pc_thu
|
||||
[geekard@geekard rel]$ objdump -t rel.o
|
||||
|
||||
rel.o: file format elf32-i386
|
||||
|
||||
SYMBOL TABLE:
|
||||
00000000 l df *ABS* 00000000 rel.c
|
||||
00000000 l d .text 00000000 .text //.text section定义
|
||||
00000000 g F __.text__ 00000005 Fun //.text section中的第一个函数(偏移量为0),本文件内定义
|
||||
00000005 g F .text 00000058 main //.text section中的第二个函数
|
||||
00000000 g F .text.x86.get_pc_thunk.bx 00000000 .hidden x86.get_pc_thunk.bx
|
||||
00000000 l d .text.x86.get_pc_thunk.bx 00000000 .text.x86.get_pc_thunk.bx
|
||||
00000000 l d .data 00000000 .data //.data section定义
|
||||
00000000 g O .data 00000004 globalVar
|
||||
00000004 l O .data 00000004 globalVarStatic
|
||||
00000008 l O .data 00000004 __staticVar.1828__
|
||||
00000000 l d .rodata 00000000 .rodata
|
||||
00000000 l d .bss 00000000 .bss
|
||||
00000004 O __*COM*__ 00000004 globalVarUninit
|
||||
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
|
||||
00000000 l d .eh_frame 00000000 .eh_frame
|
||||
00000000 l d .comment 00000000 .comment
|
||||
00000000 l d .group 00000000 .group
|
||||
00000000 __*UND*__ 00000000 _GLOBAL_OFFSET_TABLE_
|
||||
00000000 *UND* 00000000 externVar
|
||||
00000000 *UND* 00000000 printf
|
||||
00000000 *UND* 00000000 externFun
|
||||
|
||||
[geekard@geekard rel]$ gcc -S __-fPIC__ rel.c
|
||||
[geekard@geekard rel]$ cat rel.s
|
||||
.file "rel.c"
|
||||
|
||||
.globl globalVar
|
||||
.data
|
||||
.align 4
|
||||
.type globalVar, @object
|
||||
.size globalVar, 4
|
||||
globalVar:
|
||||
.long 1
|
||||
|
||||
.comm globalVarUninit,4,4
|
||||
.align 4
|
||||
|
||||
.type globalVarStatic, @object
|
||||
.size globalVarStatic, 4
|
||||
globalVarStatic:
|
||||
.long 3
|
||||
|
||||
.text
|
||||
.globl Fun
|
||||
.type Fun, @function
|
||||
Fun:
|
||||
.LFB0: **//.LFB是Dwarf使用的一个标号,与.LFE相匹配。**
|
||||
.cfi_startproc //[[../CFI_for_gas.txt|cfi(call frame information)]]
|
||||
pushl %ebp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset 5, -8
|
||||
movl %esp, %ebp
|
||||
.cfi_def_cfa_register 5
|
||||
popl %ebp
|
||||
.cfi_restore 5
|
||||
.cfi_def_cfa 4, 4
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size Fun, .-Fun
|
||||
|
||||
.section __.rodata__
|
||||
__.LC0: //该标号没有使用.globl限定,所以符号表中没有包含。只在本文件内有效。__
|
||||
.string "%d\n"
|
||||
|
||||
.text
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB1: //前面使用的是.LFB0, 所以这里是.LFB1
|
||||
.cfi_startproc
|
||||
pushl %ebp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset 5, -8
|
||||
movl %esp, %ebp
|
||||
.cfi_def_cfa_register 5
|
||||
pushl %ebx
|
||||
andl $-16, %esp
|
||||
subl $32, %esp
|
||||
.cfi_offset 3, -12
|
||||
call ____x86.get_pc_thunk.bx __**//获得IP的值,保存在ebx寄存器中**
|
||||
addl $___GLOBAL_OFFSET_TABLE___, %ebx **//通过GOTPC重定位,获得GOT与当前IP的偏移量。最终获得GOT的首地址**
|
||||
movl __globalVar@GOT__(%ebx), %eax **//通过GOT32重定位,获得var@GOT的值,即var所在的GOT条目相对GOT的偏移量。**
|
||||
movl (%eax), %eax **//eax寄存器的值为var符号的实际地址,这样间接引用获得其实际值。**
|
||||
movl %eax, 28(%esp)
|
||||
|
||||
movl externVar@GOT(%ebx), %eax
|
||||
movl (%eax), %edx
|
||||
movl globalVarUninit@GOT(%ebx), %eax
|
||||
movl %edx, (%eax)
|
||||
|
||||
movl __globalVarStatic@GOTOFF__(%ebx), %eax __//GOTOFF类型的重定位__
|
||||
movl %eax, 4(%esp)
|
||||
leal __.LC0@GOTOFF__(%ebx), %eax
|
||||
movl %eax, (%esp)
|
||||
call __printf@PLT__
|
||||
|
||||
movl __staticVar.1828@GOTOFF__(%ebx), %eax
|
||||
movl %eax, (%esp)
|
||||
call externFun@PLT
|
||||
|
||||
call Fun@PLT
|
||||
|
||||
movl -4(%ebp), %ebx
|
||||
leave
|
||||
.cfi_restore 5
|
||||
.cfi_restore 3
|
||||
.cfi_def_cfa 4, 4
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size main, .-main
|
||||
|
||||
|
||||
.data
|
||||
.align 4
|
||||
.type staticVar.1828, @object
|
||||
.size staticVar.1828, 4
|
||||
staticVar.1828:
|
||||
.long 2
|
||||
|
||||
.section .text.x86.get_pc_thunk.bx,"axG",@progbits,x86.get_pc_thunk.bx,comdat
|
||||
.globl __x86.get_pc_thunk.bx
|
||||
.hidden __x86.get_pc_thunk.bx
|
||||
.type __x86.get_pc_thunk.bx, @function
|
||||
__x86.get_pc_thunk.bx:
|
||||
.LFB2:
|
||||
.cfi_startproc
|
||||
movl (%esp), %ebx
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.LFE2:
|
||||
.ident "GCC: (GNU) 4.7.2"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
[geekard@geekard rel]$
|
||||
[geekard@geekard rel]$ objdump -d rel.o
|
||||
|
||||
rel.o: file format elf32-i386
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <Fun>:
|
||||
0: 55 push %ebp
|
||||
1: 89 e5 mov %esp,%ebp
|
||||
3: 5d pop %ebp
|
||||
4: c3 ret
|
||||
|
||||
00000005 <main>:
|
||||
5: 55 push %ebp
|
||||
6: 89 e5 mov %esp,%ebp
|
||||
8: 53 push %ebx
|
||||
9: 83 e4 f0 and $0xfffffff0,%esp
|
||||
c: 83 ec 20 sub $0x20,%esp
|
||||
f: e8 __fc ff ff ff__ call 10 <main+0xb>
|
||||
14: 81 c3 __02 00 00 00__ add $0x2,%ebx //objdump反汇编后的代码中已经__看不到原始的重定位信息__。所以需要和重定位条目一起查看。
|
||||
1a: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
|
||||
20: 8b 00 mov (%eax),%eax
|
||||
22: 89 44 24 1c mov %eax,0x1c(%esp)
|
||||
26: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
|
||||
2c: 8b 10 mov (%eax),%edx
|
||||
2e: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
|
||||
34: 89 10 mov %edx,(%eax)
|
||||
36: 8b 83 __04 00 00 00__ mov 0x4(%ebx),%eax
|
||||
3c: 89 44 24 04 mov %eax,0x4(%esp)
|
||||
40: 8d 83 __00 00 00 00__ lea 0x0(%ebx),%eax
|
||||
46: 89 04 24 mov %eax,(%esp)
|
||||
49: e8 __fc ff ff ff__ call 4a <main+0x45>
|
||||
4e: 8b 83 __08 00 00 00__ mov 0x8(%ebx),%eax
|
||||
54: 89 04 24 mov %eax,(%esp)
|
||||
57: e8 __fc ff ff ff__ call 58 <main+0x53>
|
||||
5c: e8 __fc ff ff ff__ call 5d <main+0x58>
|
||||
61: 8b 5d fc mov -0x4(%ebp),%ebx
|
||||
64: c9 leave
|
||||
65: c3 ret
|
||||
#上面黄色标记的位置需要链接器对其重定位。
|
||||
|
||||
Disassembly of section .text.__x86.get_pc_thunk.bx:
|
||||
|
||||
00000000 <__x86.get_pc_thunk.bx>:
|
||||
0: 8b 1c 24 mov (%esp),%ebx
|
||||
3: c3 ret
|
||||
[geekard@geekard rel]$
|
||||
125
Zim/Programme/elf/ld-linux调试信息.txt
Normal file
@@ -0,0 +1,125 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-16T17:34:49+08:00
|
||||
|
||||
====== ld-linux调试信息 ======
|
||||
Created Sunday 16 December 2012
|
||||
启用动态连接器调试信息输出的方法是定义变量LD_DEBUG=all
|
||||
|
||||
**[geekard@geekard hello]$ cat hello.c**
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int glb_init = 1;
|
||||
int glb_uninit;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *str = "Just a test string!";
|
||||
printf("The test string is:\"%s\"\n", str);
|
||||
printf("glb_init:%d, glb_uninit:%d\n", glb_init, glb_uninit);
|
||||
pause(); **//暂停进程,这样可以查看其内存映射情况。**
|
||||
exit(0);
|
||||
}
|
||||
[geekard@geekard hello]$ __strace -e trace=mmap2,mprotect,munmap,open,close -ELD_DEBUG=all ./hello &>log__
|
||||
^Z
|
||||
[1]+ Stopped strace -e trace=mmap2,mprotect,munmap,open,close -ELD_DEBUG=all ./hello &>log
|
||||
#上面的log文件中包含有strace的输出和hello的ld-linux.so的DEBUG信息。
|
||||
|
||||
**#4727为hello的进程号,下面命令从log中提取ld-linux.so的DEBUG信息**
|
||||
**[geekard@geekard hello]$ cat log|grep 4727>log.ld **
|
||||
|
||||
#**下面命令从log中提取hello的系统调用信息**
|
||||
**[geekard@geekard hello]$ cat log |sed '/4727/d' >log.strace**
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77b8000
|
||||
|
||||
**[geekard@geekard hello]$ readelf -l /lib/libc.so.6**
|
||||
Elf file type is DYN (Shared object file)
|
||||
Entry point __0x19760__
|
||||
There are __10__ program headers, starting at offset 52
|
||||
|
||||
Program Headers:
|
||||
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
PHDR 0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4
|
||||
INTERP 0x16b7e8 0x0016b7e8 0x0016b7e8 0x00017 0x00017 R 0x1
|
||||
[Requesting program interpreter: [[/usr/lib/ld-linux.so.2]]]
|
||||
#第一个LOAD为RE,其大小为1718236B(0x1a37dc),需要4KB对齐,所以实际需要空间1720320B,这会传给mmap2函数。
|
||||
**LOAD** __0x000000__ 0x00000000 0x00000000 __0x1a37dc__ 0x1a37dc R E 0x1000
|
||||
**LOAD** 0x1a41dc 0x001a41dc 0x001a41dc 0x02ce0 __0x058e8__ RW 0x1000
|
||||
DYNAMIC __0x1a5d9c__ 0x001a5d9c 0x001a5d9c 0x000f8 0x000f8 RW 0x4
|
||||
NOTE 0x000174 0x00000174 0x00000174 0x00044 0x00044 R 0x4
|
||||
TLS 0x1a41dc 0x001a41dc 0x001a41dc 0x00008 0x00040 R 0x4
|
||||
GNU_EH_FRAME 0x16b800 0x0016b800 0x0016b800 0x07454 0x07454 R 0x4
|
||||
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
|
||||
**GNU_RELRO** 0x1a41dc 0x001a41dc 0x001a41dc 0x01e24 0x01e24 R 0x1
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00
|
||||
01 .interp
|
||||
02 .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt .text __libc_freeres_fn __libc_thread_freeres_fn .rodata .interp .eh_frame_hdr .eh_frame .gcc_except_table .hash
|
||||
03 .tdata .init_array __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got .got.plt .data .bss
|
||||
04 .dynamic
|
||||
05 .note.gnu.build-id .note.ABI-tag
|
||||
06 .tdata .tbss
|
||||
07 .eh_frame_hdr
|
||||
08
|
||||
09 .tdata .init_array __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got
|
||||
可以看出libc.so.6中的__虚拟地址从0开始__。
|
||||
|
||||
**[geekard@geekard hello]$ pmap $(pgrep hello) |nl #查看hello进程的地址映射情况**
|
||||
1 4727: ./hello
|
||||
2 08048000 4K r-x-- /home/geekard/Code/hello/hello
|
||||
3 08049000 4K rw--- /home/geekard/Code/hello/hello
|
||||
4 __b75eb000__ 4K rw--- [ anon ] //libc的保护区域
|
||||
//0xb75ec000为ld-linux.so映射libc到a.out进程地址空间时的__随机base地址(见后文log文件)__。
|
||||
5 __b75ec000__ 1680K r-x-- /usr/lib/libc-2.16.so
|
||||
6 __b7790000__ 8K r---- /usr/lib/libc-2.16.so
|
||||
7 b7792000 4K rw--- /usr/lib/libc-2.16.so
|
||||
8 __b7793000__ 12K rw--- [ anon ]
|
||||
9 b77b8000 **8K** rw--- [ anon ] //包含有第一次调用mmap2()分配的匿名内存块。
|
||||
10 b77ba000 4K r-x-- [ anon ] //ld的保护区域
|
||||
11 b77bb000 128K r-x-- /usr/lib/ld-2.16.so
|
||||
12 b77db000 4K r---- /usr/lib/ld-2.16.so
|
||||
13 b77dc000 4K rw--- /usr/lib/ld-2.16.so
|
||||
14 __bff8b000__ 132K rw--- [ stack ]
|
||||
15 total 1996K
|
||||
|
||||
**[geekard@geekard hello]$ cat log //查看strace打印出的系统调用和ld-linux.so打印的DEBUG信息。**
|
||||
//匿名映射,mmap2的第一个参数为NULL,所以内核会随机地选择一个地址,这里为 **0xb77b9000。**
|
||||
//匿名映射的虚拟地址空间为**0xb77b9000~0xb77ba000。包含在pmap打印的第9行中。**
|
||||
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|**MAP_ANONYMOUS**, -1, 0) = **0xb77b9000**
|
||||
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
|
||||
//文件映射,内核随机选择一个起始地址,这里为**0xb7796000**
|
||||
mmap2(**NULL**, 139868, PROT_READ, MAP_PRIVATE, 3, 0) = **0xb7796000**
|
||||
4727:
|
||||
4727: file=libc.so.6 [0]; needed by ./hello [0]
|
||||
4727: find library=libc.so.6 [0]; searching
|
||||
4727: search cache=/etc/ld.so.cache
|
||||
//关闭了ld.so.cache,所以**其映射的内存区域将删除**。
|
||||
close(3) = 0
|
||||
4727: trying file=/usr/lib/libc.so.6
|
||||
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
|
||||
//文件映射,内核随机选择一个起始地址,这里为 __0xb75ec000。这里映射的是第一个LOAD segment__
|
||||
mmap2(**NULL**, 1743556, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = __0xb75ec000__
|
||||
|
||||
//这里映射的是第二个LOAD segment
|
||||
mmap2(**0xb7790000,** 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, **0x1a4**) = 0xb7790000
|
||||
|
||||
mmap2(**0xb7793000**, 10948, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|**MAP_ANONYMOUS**, -1, 0) = 0xb7793000
|
||||
close(3) = 0
|
||||
4727:
|
||||
4727: file=libc.so.6 [0]; generating link map
|
||||
|
||||
4727: dynamic: __0xb7791d9c__ base: __0xb75ec000__ size: 0x001a9ac4
|
||||
4727: entry: 0xb7605760 phdr: 0xb75ec034 phnum: 10
|
||||
4727:
|
||||
4727: checking for version `GLIBC_2.0' in file /usr/lib/libc.so.6 [0] required by file ./hello [0]
|
||||
4727: checking for version `GLIBC_2.3' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
|
||||
4727: checking for version `GLIBC_PRIVATE' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
|
||||
4727: checking for version `GLIBC_2.1' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
|
||||
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = **0xb75eb000**
|
||||
mprotect(0xb7790000, 8192, PROT_READ) = 0
|
||||
mprotect(0xb77db000, 4096, PROT_READ) = 0
|
||||
munmap(0xb7796000, 139868) = 0
|
||||
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = **0xb77b8000**
|
||||
7
Zim/Programme/goagent.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-29T11:19:39+08:00
|
||||
|
||||
====== goagent ======
|
||||
Created Saturday 29 December 2012
|
||||
|
||||
380
Zim/Programme/python/The-Python-Standard-Library.txt
Normal file
@@ -0,0 +1,380 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-29T14:30:56+08:00
|
||||
|
||||
====== The-Python-Standard-Library ======
|
||||
Created Thursday 29 November 2012
|
||||
http://docs.python.org/2/library/index.html
|
||||
|
||||
While **The Python Language Reference** describes the exact syntax and semantics of the Python language, this library reference manual describes the standard library that is distributed with Python. It also describes some of the optional components that are commonly included in Python distributions.
|
||||
|
||||
Python’s standard library is very extensive, offering a wide range of facilities as indicated by the long table of contents listed below.
|
||||
|
||||
The library contains __built-in modules__ (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, as well as modules written in Python that provide __standardized solutions__ for many problems that occur in everyday programming. Some of these modules are explicitly designed to encourage and enhance the portability of Python programs by abstracting away platform-specifics into platform-neutral APIs.
|
||||
|
||||
The Python installers for the Windows platform usually includes the entire standard library and often also include many additional components. For Unix-like operating systems Python is normally provided as **a collection of packages**, so it may be necessary to use the packaging tools provided with the operating system to obtain some or all of the optional components.
|
||||
|
||||
In addition to the standard library, there is a growing collection of several thousand components (from individual programs and modules to packages and entire application development frameworks), available from the Python Package Index.
|
||||
|
||||
1. Introduction
|
||||
2. Built-in Functions
|
||||
3. Non-essential Built-in Functions
|
||||
4. Built-in Constants
|
||||
4.1. Constants added by the site module
|
||||
5. Built-in Types
|
||||
5.1. Truth Value Testing
|
||||
5.2. Boolean Operations — and, or, not
|
||||
5.3. Comparisons
|
||||
5.4. Numeric Types — int, float, long, complex
|
||||
5.5. Iterator Types
|
||||
5.6. Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange
|
||||
5.7. Set Types — set, frozenset
|
||||
5.8. Mapping Types — dict
|
||||
5.9. File Objects
|
||||
5.10. memoryview type
|
||||
5.11. Context Manager Types
|
||||
5.12. Other Built-in Types
|
||||
5.13. Special Attributes
|
||||
6. Built-in Exceptions
|
||||
6.1. Exception hierarchy
|
||||
7. String Services
|
||||
7.1. string — Common string operations
|
||||
7.2. re — Regular expression operations
|
||||
7.3. struct — Interpret strings as packed binary data
|
||||
7.4. difflib — Helpers for computing deltas
|
||||
7.5. StringIO — Read and write strings as files
|
||||
7.6. cStringIO — Faster version of StringIO
|
||||
7.7. textwrap — Text wrapping and filling
|
||||
7.8. codecs — Codec registry and base classes
|
||||
7.9. unicodedata — Unicode Database
|
||||
7.10. stringprep — Internet String Preparation
|
||||
7.11. fpformat — Floating point conversions
|
||||
8. Data Types
|
||||
8.1. datetime — Basic date and time types
|
||||
8.2. calendar — General calendar-related functions
|
||||
8.3. collections — High-performance container datatypes
|
||||
8.4. heapq — Heap queue algorithm
|
||||
8.5. bisect — Array bisection algorithm
|
||||
8.6. array — Efficient arrays of numeric values
|
||||
8.7. sets — Unordered collections of unique elements
|
||||
8.8. sched — Event scheduler
|
||||
8.9. mutex — Mutual exclusion support
|
||||
8.10. Queue — A synchronized queue class
|
||||
8.11. weakref — Weak references
|
||||
8.12. UserDict — Class wrapper for dictionary objects
|
||||
8.13. UserList — Class wrapper for list objects
|
||||
8.14. UserString — Class wrapper for string objects
|
||||
8.15. types — Names for built-in types
|
||||
8.16. new — Creation of runtime internal objects
|
||||
8.17. copy — Shallow and deep copy operations
|
||||
8.18. pprint — Data pretty printer
|
||||
8.19. repr — Alternate repr() implementation
|
||||
9. Numeric and Mathematical Modules
|
||||
9.1. numbers — Numeric abstract base classes
|
||||
9.2. math — Mathematical functions
|
||||
9.3. cmath — Mathematical functions for complex numbers
|
||||
9.4. decimal — Decimal fixed point and floating point arithmetic
|
||||
9.5. fractions — Rational numbers
|
||||
9.6. random — Generate pseudo-random numbers
|
||||
9.7. itertools — Functions creating iterators for efficient looping
|
||||
9.8. functools — Higher-order functions and operations on callable objects
|
||||
9.9. operator — Standard operators as functions
|
||||
10. File and Directory Access
|
||||
10.1. os.path — Common pathname manipulations
|
||||
10.2. fileinput — Iterate over lines from multiple input streams
|
||||
10.3. stat — Interpreting stat() results
|
||||
10.4. statvfs — Constants used with os.statvfs()
|
||||
10.5. filecmp — File and Directory Comparisons
|
||||
10.6. tempfile — Generate temporary files and directories
|
||||
10.7. glob — Unix style pathname pattern expansion
|
||||
10.8. fnmatch — Unix filename pattern matching
|
||||
10.9. linecache — Random access to text lines
|
||||
10.10. shutil — High-level file operations
|
||||
10.11. dircache — Cached directory listings
|
||||
10.12. macpath — Mac OS 9 path manipulation functions
|
||||
11. Data Persistence
|
||||
11.1. pickle — Python object serialization
|
||||
11.2. cPickle — A faster pickle
|
||||
11.3. copy_reg — Register pickle support functions
|
||||
11.4. shelve — Python object persistence
|
||||
11.5. marshal — Internal Python object serialization
|
||||
11.6. anydbm — Generic access to DBM-style databases
|
||||
11.7. whichdb — Guess which DBM module created a database
|
||||
11.8. dbm — Simple “database” interface
|
||||
11.9. gdbm — GNU’s reinterpretation of dbm
|
||||
11.10. dbhash — DBM-style interface to the BSD database library
|
||||
11.11. bsddb — Interface to Berkeley DB library
|
||||
11.12. dumbdbm — Portable DBM implementation
|
||||
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases
|
||||
12. Data Compression and Archiving
|
||||
12.1. zlib — Compression compatible with gzip
|
||||
12.2. gzip — Support for gzip files
|
||||
12.3. bz2 — Compression compatible with bzip2
|
||||
12.4. zipfile — Work with ZIP archives
|
||||
12.5. tarfile — Read and write tar archive files
|
||||
13. File Formats
|
||||
13.1. csv — CSV File Reading and Writing
|
||||
13.2. ConfigParser — Configuration file parser
|
||||
13.3. robotparser — Parser for robots.txt
|
||||
13.4. netrc — netrc file processing
|
||||
13.5. xdrlib — Encode and decode XDR data
|
||||
13.6. plistlib — Generate and parse Mac OS X .plist files
|
||||
14. Cryptographic Services
|
||||
14.1. hashlib — Secure hashes and message digests
|
||||
14.2. hmac — Keyed-Hashing for Message Authentication
|
||||
14.3. md5 — MD5 message digest algorithm
|
||||
14.4. sha — SHA-1 message digest algorithm
|
||||
15. Generic Operating System Services
|
||||
15.1. os — Miscellaneous operating system interfaces
|
||||
15.2. io — Core tools for working with streams
|
||||
15.3. time — Time access and conversions
|
||||
15.4. argparse — Parser for command-line options, arguments and sub-commands
|
||||
15.5. optparse — Parser for command line options
|
||||
15.6. getopt — C-style parser for command line options
|
||||
15.7. logging — Logging facility for Python
|
||||
15.8. logging.config — Logging configuration
|
||||
15.9. logging.handlers — Logging handlers
|
||||
15.10. getpass — Portable password input
|
||||
15.11. curses — Terminal handling for character-cell displays
|
||||
15.12. curses.textpad — Text input widget for curses programs
|
||||
15.13. curses.ascii — Utilities for ASCII characters
|
||||
15.14. curses.panel — A panel stack extension for curses
|
||||
15.15. platform — Access to underlying platform’s identifying data
|
||||
15.16. errno — Standard errno system symbols
|
||||
15.17. ctypes — A foreign function library for Python
|
||||
16. Optional Operating System Services
|
||||
16.1. select — Waiting for I/O completion
|
||||
16.2. threading — Higher-level threading interface
|
||||
16.3. thread — Multiple threads of control
|
||||
16.4. dummy_threading — Drop-in replacement for the threading module
|
||||
16.5. dummy_thread — Drop-in replacement for the thread module
|
||||
16.6. multiprocessing — Process-based “threading” interface
|
||||
16.7. mmap — Memory-mapped file support
|
||||
16.8. readline — GNU readline interface
|
||||
16.9. rlcompleter — Completion function for GNU readline
|
||||
17. Interprocess Communication and Networking
|
||||
17.1. subprocess — Subprocess management
|
||||
17.2. socket — Low-level networking interface
|
||||
17.3. ssl — TLS/SSL wrapper for socket objects
|
||||
17.4. signal — Set handlers for asynchronous events
|
||||
17.5. popen2 — Subprocesses with accessible I/O streams
|
||||
17.6. asyncore — Asynchronous socket handler
|
||||
17.7. asynchat — Asynchronous socket command/response handler
|
||||
18. Internet Data Handling
|
||||
18.1. email — An email and MIME handling package
|
||||
18.2. json — JSON encoder and decoder
|
||||
18.3. mailcap — Mailcap file handling
|
||||
18.4. mailbox — Manipulate mailboxes in various formats
|
||||
18.5. mhlib — Access to MH mailboxes
|
||||
18.6. mimetools — Tools for parsing MIME messages
|
||||
18.7. mimetypes — Map filenames to MIME types
|
||||
18.8. MimeWriter — Generic MIME file writer
|
||||
18.9. mimify — MIME processing of mail messages
|
||||
18.10. multifile — Support for files containing distinct parts
|
||||
18.11. rfc822 — Parse RFC 2822 mail headers
|
||||
18.12. base64 — RFC 3548: Base16, Base32, Base64 Data Encodings
|
||||
18.13. binhex — Encode and decode binhex4 files
|
||||
18.14. binascii — Convert between binary and ASCII
|
||||
18.15. quopri — Encode and decode MIME quoted-printable data
|
||||
18.16. uu — Encode and decode uuencode files
|
||||
19. Structured Markup Processing Tools
|
||||
19.1. HTMLParser — Simple HTML and XHTML parser
|
||||
19.2. sgmllib — Simple SGML parser
|
||||
19.3. htmllib — A parser for HTML documents
|
||||
19.4. htmlentitydefs — Definitions of HTML general entities
|
||||
19.5. xml.etree.ElementTree — The ElementTree XML API
|
||||
19.6. xml.dom — The Document Object Model API
|
||||
19.7. xml.dom.minidom — Lightweight DOM implementation
|
||||
19.8. xml.dom.pulldom — Support for building partial DOM trees
|
||||
19.9. xml.sax — Support for SAX2 parsers
|
||||
19.10. xml.sax.handler — Base classes for SAX handlers
|
||||
19.11. xml.sax.saxutils — SAX Utilities
|
||||
19.12. xml.sax.xmlreader — Interface for XML parsers
|
||||
19.13. xml.parsers.expat — Fast XML parsing using Expat
|
||||
20. Internet Protocols and Support
|
||||
20.1. webbrowser — Convenient Web-browser controller
|
||||
20.2. cgi — Common Gateway Interface support
|
||||
20.3. cgitb — Traceback manager for CGI scripts
|
||||
20.4. wsgiref — WSGI Utilities and Reference Implementation
|
||||
20.5. urllib — Open arbitrary resources by URL
|
||||
20.6. urllib2 — extensible library for opening URLs
|
||||
20.7. httplib — HTTP protocol client
|
||||
20.8. ftplib — FTP protocol client
|
||||
20.9. poplib — POP3 protocol client
|
||||
20.10. imaplib — IMAP4 protocol client
|
||||
20.11. nntplib — NNTP protocol client
|
||||
20.12. smtplib — SMTP protocol client
|
||||
20.13. smtpd — SMTP Server
|
||||
20.14. telnetlib — Telnet client
|
||||
20.15. uuid — UUID objects according to RFC 4122
|
||||
20.16. urlparse — Parse URLs into components
|
||||
20.17. SocketServer — A framework for network servers
|
||||
20.18. BaseHTTPServer — Basic HTTP server
|
||||
20.19. SimpleHTTPServer — Simple HTTP request handler
|
||||
20.20. CGIHTTPServer — CGI-capable HTTP request handler
|
||||
20.21. cookielib — Cookie handling for HTTP clients
|
||||
20.22. Cookie — HTTP state management
|
||||
20.23. xmlrpclib — XML-RPC client access
|
||||
20.24. SimpleXMLRPCServer — Basic XML-RPC server
|
||||
20.25. DocXMLRPCServer — Self-documenting XML-RPC server
|
||||
21. Multimedia Services
|
||||
21.1. audioop — Manipulate raw audio data
|
||||
21.2. imageop — Manipulate raw image data
|
||||
21.3. aifc — Read and write AIFF and AIFC files
|
||||
21.4. sunau — Read and write Sun AU files
|
||||
21.5. wave — Read and write WAV files
|
||||
21.6. chunk — Read IFF chunked data
|
||||
21.7. colorsys — Conversions between color systems
|
||||
21.8. imghdr — Determine the type of an image
|
||||
21.9. sndhdr — Determine type of sound file
|
||||
21.10. ossaudiodev — Access to OSS-compatible audio devices
|
||||
22. Internationalization
|
||||
22.1. gettext — Multilingual internationalization services
|
||||
22.2. locale — Internationalization services
|
||||
23. Program Frameworks
|
||||
23.1. cmd — Support for line-oriented command interpreters
|
||||
23.2. shlex — Simple lexical analysis
|
||||
24. Graphical User Interfaces with Tk
|
||||
24.1. Tkinter — Python interface to Tcl/Tk
|
||||
24.2. ttk — Tk themed widgets
|
||||
24.3. Tix — Extension widgets for Tk
|
||||
24.4. ScrolledText — Scrolled Text Widget
|
||||
24.5. turtle — Turtle graphics for Tk
|
||||
24.6. IDLE
|
||||
24.7. Other Graphical User Interface Packages
|
||||
25. Development Tools
|
||||
25.1. pydoc — Documentation generator and online help system
|
||||
25.2. doctest — Test interactive Python examples
|
||||
25.3. unittest — Unit testing framework
|
||||
25.4. 2to3 - Automated Python 2 to 3 code translation
|
||||
25.5. test — Regression tests package for Python
|
||||
25.6. test.test_support — Utility functions for tests
|
||||
26. Debugging and Profiling
|
||||
26.1. bdb — Debugger framework
|
||||
26.2. pdb — The Python Debugger
|
||||
26.3. Debugger Commands
|
||||
26.4. The Python Profilers
|
||||
26.5. hotshot — High performance logging profiler
|
||||
26.6. timeit — Measure execution time of small code snippets
|
||||
26.7. trace — Trace or track Python statement execution
|
||||
27. Python Runtime Services
|
||||
27.1. sys — System-specific parameters and functions
|
||||
27.2. sysconfig — Provide access to Python’s configuration information
|
||||
27.3. __builtin__ — Built-in objects
|
||||
27.4. future_builtins — Python 3 builtins
|
||||
27.5. __main__ — Top-level script environment
|
||||
27.6. warnings — Warning control
|
||||
27.7. contextlib — Utilities for with-statement contexts
|
||||
27.8. abc — Abstract Base Classes
|
||||
27.9. atexit — Exit handlers
|
||||
27.10. traceback — Print or retrieve a stack traceback
|
||||
27.11. __future__ — Future statement definitions
|
||||
27.12. gc — Garbage Collector interface
|
||||
27.13. inspect — Inspect live objects
|
||||
27.14. site — Site-specific configuration hook
|
||||
27.15. user — User-specific configuration hook
|
||||
27.16. fpectl — Floating point exception control
|
||||
27.17. distutils — Building and installing Python modules
|
||||
28. Custom Python Interpreters
|
||||
28.1. code — Interpreter base classes
|
||||
28.2. codeop — Compile Python code
|
||||
29. Restricted Execution
|
||||
29.1. rexec — Restricted execution framework
|
||||
29.2. Bastion — Restricting access to objects
|
||||
30. Importing Modules
|
||||
30.1. imp — Access the import internals
|
||||
30.2. importlib – Convenience wrappers for __import__()
|
||||
30.3. imputil — Import utilities
|
||||
30.4. zipimport — Import modules from Zip archives
|
||||
30.5. pkgutil — Package extension utility
|
||||
30.6. modulefinder — Find modules used by a script
|
||||
30.7. runpy — Locating and executing Python modules
|
||||
31. Python Language Services
|
||||
31.1. parser — Access Python parse trees
|
||||
31.2. ast — Abstract Syntax Trees
|
||||
31.3. symtable — Access to the compiler’s symbol tables
|
||||
31.4. symbol — Constants used with Python parse trees
|
||||
31.5. token — Constants used with Python parse trees
|
||||
31.6. keyword — Testing for Python keywords
|
||||
31.7. tokenize — Tokenizer for Python source
|
||||
31.8. tabnanny — Detection of ambiguous indentation
|
||||
31.9. pyclbr — Python class browser support
|
||||
31.10. py_compile — Compile Python source files
|
||||
31.11. compileall — Byte-compile Python libraries
|
||||
31.12. dis — Disassembler for Python bytecode
|
||||
31.13. pickletools — Tools for pickle developers
|
||||
32. Python compiler package
|
||||
32.1. The basic interface
|
||||
32.2. Limitations
|
||||
32.3. Python Abstract Syntax
|
||||
32.4. Using Visitors to Walk ASTs
|
||||
32.5. Bytecode Generation
|
||||
33. Miscellaneous Services
|
||||
33.1. formatter — Generic output formatting
|
||||
34. MS Windows Specific Services
|
||||
34.1. msilib — Read and write Microsoft Installer files
|
||||
34.2. msvcrt – Useful routines from the MS VC++ runtime
|
||||
34.3. _winreg – Windows registry access
|
||||
34.4. winsound — Sound-playing interface for Windows
|
||||
35. Unix Specific Services
|
||||
35.1. posix — The most common POSIX system calls
|
||||
35.2. pwd — The password database
|
||||
35.3. spwd — The shadow password database
|
||||
35.4. grp — The group database
|
||||
35.5. crypt — Function to check Unix passwords
|
||||
35.6. dl — Call C functions in shared objects
|
||||
35.7. termios — POSIX style tty control
|
||||
35.8. tty — Terminal control functions
|
||||
35.9. pty — Pseudo-terminal utilities
|
||||
35.10. fcntl — The fcntl() and ioctl() system calls
|
||||
35.11. pipes — Interface to shell pipelines
|
||||
35.12. posixfile — File-like objects with locking support
|
||||
35.13. resource — Resource usage information
|
||||
35.14. nis — Interface to Sun’s NIS (Yellow Pages)
|
||||
35.15. syslog — Unix syslog library routines
|
||||
35.16. commands — Utilities for running commands
|
||||
36. Mac OS X specific services
|
||||
36.1. ic — Access to the Mac OS X Internet Config
|
||||
36.2. MacOS — Access to Mac OS interpreter features
|
||||
36.3. macostools — Convenience routines for file manipulation
|
||||
36.4. findertools — The finder‘s Apple Events interface
|
||||
36.5. EasyDialogs — Basic Macintosh dialogs
|
||||
36.6. FrameWork — Interactive application framework
|
||||
36.7. autoGIL — Global Interpreter Lock handling in event loops
|
||||
36.8. Mac OS Toolbox Modules
|
||||
36.9. ColorPicker — Color selection dialog
|
||||
37. MacPython OSA Modules
|
||||
37.1. gensuitemodule — Generate OSA stub packages
|
||||
37.2. aetools — OSA client support
|
||||
37.3. aepack — Conversion between Python variables and AppleEvent data containers
|
||||
37.4. aetypes — AppleEvent objects
|
||||
37.5. MiniAEFrame — Open Scripting Architecture server support
|
||||
38. SGI IRIX Specific Services
|
||||
38.1. al — Audio functions on the SGI
|
||||
38.2. AL — Constants used with the al module
|
||||
38.3. cd — CD-ROM access on SGI systems
|
||||
38.4. fl — FORMS library for graphical user interfaces
|
||||
38.5. FL — Constants used with the fl module
|
||||
38.6. flp — Functions for loading stored FORMS designs
|
||||
38.7. fm — Font Manager interface
|
||||
38.8. gl — Graphics Library interface
|
||||
38.9. DEVICE — Constants used with the gl module
|
||||
38.10. GL — Constants used with the gl module
|
||||
38.11. imgfile — Support for SGI imglib files
|
||||
38.12. jpeg — Read and write JPEG files
|
||||
39. SunOS Specific Services
|
||||
39.1. sunaudiodev — Access to Sun audio hardware
|
||||
39.2. SUNAUDIODEV — Constants used with sunaudiodev
|
||||
40. Undocumented Modules
|
||||
40.1. Miscellaneous useful utilities
|
||||
40.2. Platform specific modules
|
||||
40.3. Multimedia
|
||||
40.4. Undocumented Mac OS modules
|
||||
40.5. Obsolete
|
||||
40.6. SGI-specific Extension modules
|
||||
»
|
||||
indexmodules |next |previous | Python » Documentation »
|
||||
© Copyright 1990-2012, Python Software Foundation.
|
||||
The Python Software Foundation is a non-profit corporation. Please donate.
|
||||
Last updated on Dec 01, 2012. Found a bug?
|
||||
Created using Sphinx 1.0.7.
|
||||
@@ -0,0 +1,22 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-02T16:34:03+08:00
|
||||
|
||||
====== 1. Introduction ======
|
||||
Created Sunday 02 December 2012
|
||||
|
||||
===== 1. Introduction =====
|
||||
The “Python library” contains several different kinds of components.
|
||||
|
||||
It contains __data types__ that would normally be considered part of the “core” of a language, such as **numbers and lists**. For these types, the Python language core defines the form of **literals** and places some constraints on their semantics, but does **not fully define** the semantics. (On the other hand, the language core does define syntactic properties like the spelling and priorities of operators.)
|
||||
|
||||
The library also contains __built-in functions and exceptions__ — objects that can be used by all Python code //without the need of an import statement//. Some of these are defined by the core language, but many are not essential for the core semantics and are only described here.
|
||||
|
||||
The bulk of the __library__, however, consists of a collection of modules. There are many ways to dissect this collection. Some modules are written in C and __built in__** to the Python interpreter**; others are written in Python and imported in source form.
|
||||
|
||||
Some modules provide interfaces that are highly specific to Python, like printing a stack trace; some provide interfaces that are specific to particular operating systems, such as access to specific hardware; others provide interfaces that are specific to a particular application domain, like the World Wide Web. Some modules are available in all versions and ports of Python; others are only available when the underlying system supports or requires them; yet others are available only when a particular configuration option was chosen at the time when Python was compiled and installed.
|
||||
|
||||
This manual is organized **“from the inside out:”** it first describes the built-in data types, then the built-in functions and exceptions, and finally the modules, grouped in chapters of related modules. The ordering of the chapters as well as the ordering of the modules within each chapter is roughly from most relevant to least important.
|
||||
|
||||
|
||||
Let the show begin!
|
||||
@@ -0,0 +1,892 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-02T16:37:06+08:00
|
||||
|
||||
====== 2. Built-in Functions ======
|
||||
Created Sunday 02 December 2012
|
||||
|
||||
The Python interpreter has a number of functions built into it that are __always available__. They are listed here in alphabetical order.
|
||||
|
||||
abs() divmod() input() open() staticmethod()
|
||||
all() enumerate() int() ord() str()
|
||||
any() eval() isinstance() pow() sum()
|
||||
basestring() execfile() issubclass() print() super()
|
||||
bin() file() iter() property() tuple()
|
||||
bool() filter() len() range() type()
|
||||
bytearray() float() list() raw_input() unichr()
|
||||
callable() format() locals() reduce() unicode()
|
||||
chr() frozenset() long() reload() vars()
|
||||
classmethod() getattr() map() repr() xrange()
|
||||
cmp() globals() max() reversed() zip()
|
||||
compile() hasattr() memoryview() round() __import__()
|
||||
complex() hash() min() set() apply()
|
||||
delattr() help() next() setattr() buffer()
|
||||
dict() hex() object() slice() coerce()
|
||||
dir() id() oct() sorted() intern()
|
||||
|
||||
===== abs(x) =====
|
||||
Return the absolute value of **a number**. The argument may be a plain or long integer or a floating point number. If the argument is a complex number, its magnitude is returned.
|
||||
|
||||
===== all(iterable) =====
|
||||
Return True if **all elements** of the iterable are true (or if the iterable is empty). Equivalent to:
|
||||
|
||||
def all(iterable):
|
||||
for element in iterable:
|
||||
if not element:
|
||||
return False
|
||||
return True
|
||||
New in version 2.5.
|
||||
|
||||
===== any(iterable) =====
|
||||
Return True if **any element** of the iterable is true. If the iterable is empty, return False. Equivalent to:
|
||||
|
||||
def any(iterable):
|
||||
for element in iterable:
|
||||
if element:
|
||||
return True
|
||||
return False
|
||||
New in version 2.5.
|
||||
|
||||
===== basestring() =====
|
||||
__This abstract type is the superclass for str and unicode. It cannot be called or instantiated__, but it can be used to test whether an object is an instance of str or unicode. **isinstance(obj, basestring)** is equivalent to isinstance(obj, (str, unicode)).
|
||||
basestring其实是一个抽象类,它是str和unicode的基类,不能被实例化。
|
||||
New in version 2.3.
|
||||
|
||||
===== bin(x) =====
|
||||
x需要为int或long类型,否则需要定义__index__()方法。
|
||||
Convert an __integer number__ to a binary string. The result is a valid Python expression. If x is not a Python int object, it has to define an **__index__()** method that returns an integer.
|
||||
|
||||
=== 实例: ===
|
||||
**>>> bin(123.22)**
|
||||
**Traceback (most recent call last):**
|
||||
** File "<stdin>", line 1, in <module>**
|
||||
**TypeError: 'float' object cannot be interpreted as an index**
|
||||
**>>>**
|
||||
|
||||
New in version 2.6.
|
||||
|
||||
===== bool([x]) =====
|
||||
Convert a value to a Boolean, using the standard truth testing procedure. If x is false or omitted, this returns **False**; otherwise it returns True. __bool is also a class__, which is a subclass of int. Class bool cannot be subclassed further. Its only instances are False and True.
|
||||
__False和True时class bool的实例。__
|
||||
New in version 2.2.1.
|
||||
|
||||
Changed in version 2.3: If no argument is given, this function returns False.
|
||||
|
||||
===== bytearray([source[, encoding[, errors]]]) =====
|
||||
Return a new array of bytes. The bytearray type __is a mutable sequence of integers in the range 0 <= x < 256__. It has most of the usual methods of mutable sequences, described in Mutable Sequence Types, as well as most methods that the str type has, see String Methods.
|
||||
|
||||
The optional source parameter can be used to initialize the array in a few different ways:
|
||||
|
||||
* If it is a **string**, you must also give the encoding (and optionally, errors) parameters; bytearray() then converts the string to bytes using str.encode().
|
||||
* If it is an **integer**, __the array will have that size__ and will be initialized with null bytes.
|
||||
* If it is an **object** conforming to the buffer interface, a read-only buffer of the object will be used to initialize the bytes array.
|
||||
* If it is an **iterable**, it must be an iterable of integers in the range 0 <= x < 256, which are used as the initial contents of the array.
|
||||
Without an argument, an array of **size 0** is created.
|
||||
|
||||
New in version 2.6.
|
||||
|
||||
===== callable(object) =====
|
||||
Return True if the object argument appears callable, False if not. If this returns true, it is still possible that a call fails, but if it is false, calling object will never succeed. Note that **classes are callable** (calling a class returns a new instance); class instances are callable if they have a __call__() method.
|
||||
|
||||
===== chr(i) =====
|
||||
Return **a string of one character** whose ASCII code is the integer i. For example, chr(97) returns the string 'a'. This is the inverse of **ord()**. The argument must be in the range [0..255], inclusive; ValueError will be raised if i is outside that range. See also unichr().
|
||||
|
||||
===== classmethod(function) =====
|
||||
Return a class method for function.
|
||||
|
||||
A class method receives the class as __implicit first argument__, just like an instance method receives the instance. To declare a class method, use this idiom:
|
||||
|
||||
class C:
|
||||
**@classmethod //不可少,否则调用时解释器不会自动将class传给f函数。**
|
||||
def f(cls, arg1, arg2, ...): ...
|
||||
The @classmethod form is a function **decorator** – see the description of function definitions in Function definitions for details.
|
||||
|
||||
It can be called either on the **class (such as C.f()) or on an instance (such as C().f())**. The instance is **ignored** except for its class. If a class method is called for a derived class, the derived **class object** is passed as the implied first argument.
|
||||
__classmethod修饰器,用来修饰一个class method。可以通过class或实例来调用该class method,解释器会将class或instance所属的class默认传给class method。__
|
||||
|
||||
Class methods are different than C++ or Java static methods. If you want those, see **staticmethod()** in this section.
|
||||
|
||||
For more information on class methods, consult the documentation on the standard type hierarchy in The standard type hierarchy.
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
Changed in version 2.4: Function decorator syntax added.
|
||||
|
||||
===== cmp(x, y) =====
|
||||
Compare the two objects x and y and __return an integer__ according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.
|
||||
|
||||
===== compile(source, filename, mode[, flags[, dont_inherit]]) =====
|
||||
Compile the source into **a code object or AST object**. Code objects can be executed by an __exec__ statement or evaluated by a call to __eval().__ source can either be a string or an AST object. Refer to the ast module documentation for information on how to work with AST objects.
|
||||
|
||||
The filename argument should give the file from which the code was read; pass some recognizable value if it wasn’t read from a file ('<string>' is commonly used).
|
||||
|
||||
The mode argument specifies **what kind of code** must be compiled; it can be __'exec'__ if source consists of a sequence of statements, __'eval'__ if it consists of a single expression, or __'single'__ if it consists of a single interactive statement (in the latter case, expression statements that evaluate to something other than None will be printed).
|
||||
|
||||
The optional arguments flags and dont_inherit control which future statements (see PEP 236) affect the compilation of source. If neither is present (or both are zero) the code is compiled with those future statements that are in effect in the code that is calling compile. If the flags argument is given and dont_inherit is not (or is zero) then the future statements specified by the flags argument are used in addition to those that would be used anyway. If dont_inherit is a non-zero integer then the flags argument is it – the future statements in effect around the call to compile are ignored.
|
||||
|
||||
Future statements are specified by bits which can be bitwise ORed together to specify multiple statements. The bitfield required to specify a given feature can be found as the compiler_flag attribute on the _Feature instance in the __future__ module.
|
||||
|
||||
This function raises SyntaxError if the compiled source is invalid, and TypeError if the source contains null bytes.
|
||||
|
||||
Note When compiling **a string with multi-line code** in 'single' or 'eval' mode, input must be terminated by at least one newline character. This is to facilitate detection of incomplete and complete statements in the code module.
|
||||
Changed in version 2.3: The flags and dont_inherit arguments were added.
|
||||
|
||||
Changed in version 2.6: Support for compiling AST objects.
|
||||
|
||||
Changed in version 2.7: Allowed use of Windows and Mac newlines. Also input in 'exec' mode does not have to end in a newline anymore.
|
||||
|
||||
===== complex([real[, imag]]) =====
|
||||
Create a complex number with the value real + imag*j or convert a string or number to a complex number. If the first parameter is a string, it will be interpreted as a complex number and the function must be called without a second parameter. The second parameter can never be a string. Each argument may be any numeric type (including complex). If imag is omitted, it defaults to zero and the function serves as a numeric conversion function like int(), long() and float(). If both arguments are omitted, returns 0j.
|
||||
|
||||
Note When converting from a string, the string must not contain whitespace around the central + or - operator. For example, complex('1+2j') is fine, but complex('1 + 2j') raises ValueError.
|
||||
The complex type is described in Numeric Types — int, float, long, complex.
|
||||
|
||||
===== delattr(object, name) =====
|
||||
This is a relative of setattr(). The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it. For example, **delattr(x, 'foobar')** is equivalent to **del x.foobar**.
|
||||
|
||||
===== dict(**kwarg) =====
|
||||
|
||||
===== dict(mapping, **kwarg) =====
|
||||
|
||||
===== dict(iterable, **kwarg) =====
|
||||
Create a new dictionary. The dict object is the dictionary class. See dict and Mapping Types — dict for documentation about this class.
|
||||
|
||||
For other containers see the built-in list, set, and tuple classes, as well as the collections module.
|
||||
|
||||
===== dir([object]) =====
|
||||
Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.
|
||||
|
||||
If the object has a method named __dir__(), this method will be called and must return the list of attributes. This allows objects that implement a custom __getattr__() or __getattribute__() function to customize the way dir() reports their attributes.
|
||||
|
||||
If the object does not provide __dir__(), the function tries its best to gather information from the object’s __dict__ attribute, if defined, and from its type object. The resulting list is not necessarily complete, and may be inaccurate when the object has a custom __getattr__().
|
||||
|
||||
The default dir() mechanism behaves differently with different types of objects, as it attempts to produce the most relevant, rather than complete, information:
|
||||
|
||||
* If the object is a module object, the list contains the names of the module’s attributes.
|
||||
* If the object is a type or class object, the list contains the names of its attributes, and recursively of the attributes of its bases.
|
||||
* Otherwise, the list contains the object’s attributes’ names, the names of its class’s attributes, and recursively of the attributes of its class’s base classes.
|
||||
The resulting list is sorted alphabetically. For example:
|
||||
|
||||
>>>
|
||||
>>> import struct
|
||||
>>> dir() # show the names in the module namespace
|
||||
['__builtins__', '__doc__', '__name__', 'struct']
|
||||
>>> dir(struct) # show the names in the struct module
|
||||
['Struct', '__builtins__', '__doc__', '__file__', '__name__',
|
||||
'__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
|
||||
'unpack', 'unpack_from']
|
||||
>>> class Shape(object):
|
||||
def __dir__(self):
|
||||
return ['area', 'perimeter', 'location']
|
||||
>>> s = Shape()
|
||||
>>> dir(s)
|
||||
['area', 'perimeter', 'location']
|
||||
Note Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.
|
||||
|
||||
===== divmod(a, b) =====
|
||||
Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder when using long division. With mixed operand types, the rules for binary arithmetic operators apply. For plain and long integers, the result is the same as (a // b, a % b). For floating point numbers the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that. In any case q * b + a % b is very close to a, if a % b is non-zero it has the same sign as b, and 0 <= abs(a % b) < abs(b).
|
||||
|
||||
Changed in version 2.3: Using divmod() with complex numbers is deprecated.
|
||||
|
||||
===== enumerate(sequence, start=0) =====
|
||||
Return an enumerate object. sequence must be a sequence, an iterator, or some other object which supports iteration. The next() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over sequence:
|
||||
|
||||
>>>
|
||||
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
|
||||
>>> list(enumerate(seasons))
|
||||
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
|
||||
>>> list(enumerate(seasons, start=1))
|
||||
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
|
||||
Equivalent to:
|
||||
|
||||
def enumerate(sequence, start=0):
|
||||
n = start
|
||||
for elem in sequence:
|
||||
**yield n, elem**
|
||||
n += 1
|
||||
New in version 2.3.
|
||||
|
||||
Changed in version 2.6: The start parameter was added.
|
||||
|
||||
===== eval(expression[, globals[, locals]]) =====
|
||||
The arguments are a string and optional globals and locals. If provided, globals must be a dictionary. If provided, locals can be any mapping object.
|
||||
|
||||
Changed in version 2.4: formerly locals was required to be a dictionary.
|
||||
|
||||
The expression argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the globals and locals dictionaries as global and local namespace. If the globals dictionary is present and lacks ‘__builtins__’, the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard __builtin__ module and restricted environments are propagated. If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where eval() is called. The return value is the result of the evaluated expression. Syntax errors are reported as exceptions. Example:
|
||||
|
||||
>>>
|
||||
>>> x = 1
|
||||
>>> print eval('x+1')
|
||||
2
|
||||
This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string. If the code object has been compiled with 'exec' as the mode argument, eval()‘s return value will be None.
|
||||
|
||||
Hints: dynamic execution of statements is supported by the exec statement. Execution of statements from a file is supported by the execfile() function. The globals() and locals() functions returns the current global and local dictionary, respectively, which may be useful to pass around for use by eval() or execfile().
|
||||
|
||||
See ast.literal_eval() for a function that can safely evaluate strings with expressions containing only literals.
|
||||
|
||||
===== execfile(filename[, globals[, locals]]) =====
|
||||
This function is similar to __the exec statement__, but parses a file instead of a string. It is different from the import statement in that it does not use the module administration — it reads the file unconditionally and does not create a new module. [1]
|
||||
|
||||
The arguments are a file name and two optional dictionaries. The file is parsed and evaluated as a sequence of Python statements (similarly to a module) using the globals and locals dictionaries as global and local namespace. If provided, locals can be any mapping object. Remember that **at module level, globals and locals are the same dictionary**. If two separate objects are passed as globals and locals, the code will be executed as if it were embedded in a class definition.
|
||||
|
||||
Changed in version 2.4: formerly locals was required to be a dictionary.
|
||||
|
||||
__If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where execfile() is called.__ The return value is None.
|
||||
|
||||
Note The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function execfile() returns. execfile() cannot be used reliably to modify a function’s locals.
|
||||
|
||||
===== file(name[, mode[, buffering]]) =====
|
||||
file其实时class file的构造函数。
|
||||
Constructor function for the **file type**, described further in section File Objects. The constructor’s arguments are the same as those of the open() built-in function described below.
|
||||
|
||||
When opening a file, it’s preferable to use open() instead of invoking this constructor directly. file is more suited to type testing (for example, writing isinstance(f, file)).
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
===== filter(function, iterable) =====
|
||||
Construct a list from those elements of iterable __for which function returns true__. iterable may be either a sequence, a container which supports iteration, or an iterator.
|
||||
|
||||
**If iterable is a string or a tuple, the result also has that type; otherwise it is always a list.**
|
||||
If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.
|
||||
|
||||
**如果可迭代对象是字符串或tuple,则结果也为字符串或tuple,其它的都为list。**
|
||||
**如果function为None,则结果为iterable中去掉判断为False的元素。**
|
||||
|
||||
Note that **filter(function, iterable) is equivalent to [item for item in iterable if function(item)]** if function is not None and [item for item in iterable if item] if function is None.
|
||||
|
||||
See **itertools.ifilter() and itertools.ifilterfalse() f**or iterator versions of this function, including a variation that filters for elements where the function returns false.
|
||||
|
||||
===== float([x]) =====
|
||||
Convert a string or a number to floating point.
|
||||
|
||||
If the argument is a string, it must contain a possibly signed decimal or floating point number, __possibly embedded in whitespace(空格, \t, \r, \n, \v, \f)__.
|
||||
|
||||
__如果x为string,则x只能为十进制整型和浮点型字符串(则是因为float函数不像int函数那样含有可选的base参数,__
|
||||
__可以猜测或指定数字的进制类型),同时可以包含空字符。__The argument may also be **[+|-]nan or [+|-]inf**.
|
||||
|
||||
Otherwise, the argument may be **a plain** or long integer or a floating point number, and a floating point number with the same value (within Python’s floating point precision) is returned. If no argument is given, returns 0.0.
|
||||
|
||||
Note When passing in a string, values for **NaN** and **Infinity** may be returned, depending on the underlying C library. Float accepts the strings **nan, inf and -inf** for **NaN** and **positive or negative infinity**. The case and a leading + are ignored as well as a leading - is ignored for NaN. Float always represents NaN and infinity as nan, inf or -inf.
|
||||
The float type is described in Numeric Types — int, float, long, complex.
|
||||
>>> float(__0xff__)
|
||||
255.0
|
||||
>>> float(__'0xff'__)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
ValueError: invalid literal for float(): 0xff
|
||||
>>>
|
||||
>>> float('__+inf'__)
|
||||
inf
|
||||
>>> float('+nan')
|
||||
nan
|
||||
>>>
|
||||
>>> float(__'123'__)
|
||||
123.0
|
||||
>>> float(__'123\n\r\v'__)
|
||||
123.0
|
||||
>>>
|
||||
>>> float(__+nan__)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
NameError: name **'nan' is not defined**
|
||||
>>>
|
||||
|
||||
|
||||
===== format(value[, format_spec]) =====
|
||||
Convert a value to a “formatted” representation, as controlled by **format_spec**. The interpretation of format_spec will depend on the type of the value argument, however there is a standard formatting syntax that is used by most built-in types: Format Specification Mini-Language.
|
||||
|
||||
Note format(value, format_spec) merely calls **value.__format__(format_spec)**.
|
||||
New in version 2.6.
|
||||
|
||||
===== frozenset([iterable]) =====
|
||||
Return a new frozenset object, optionally with elements taken from iterable. frozenset is a built-in class. See frozenset and Set Types — set, frozenset for documentation about this class.
|
||||
|
||||
For other containers see the built-in set, list, tuple, and dict classes, as well as the __collections__ module.
|
||||
|
||||
New in version 2.4.
|
||||
|
||||
===== getattr(object, name[, default]) =====
|
||||
Return the value of the named attribute of object. **name must be a string**. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
|
||||
|
||||
===== globals() =====
|
||||
Return a dictionary representing __the current global symbol table__. This is always the dictionary of the current module (inside a function or method, this is the module where it is **defined**, not the module from which it is called).
|
||||
|
||||
===== hasattr(object, name) =====
|
||||
The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)
|
||||
|
||||
===== hash(object) =====
|
||||
Return the hash value of the object (if it has one). **Hash values are integers**. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0).
|
||||
|
||||
===== help([object]) =====
|
||||
Invoke the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.
|
||||
|
||||
This function is added to the built-in namespace by the site module.
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
===== hex(x) =====
|
||||
Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression.
|
||||
|
||||
Note To obtain a hexadecimal string representation for a float, use the __float.hex()__ method.
|
||||
Changed in version 2.4: Formerly only returned an unsigned literal.
|
||||
|
||||
===== id(object) =====
|
||||
Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
|
||||
|
||||
CPython implementation detail: This is **the address of the object in memory**.
|
||||
|
||||
===== input([prompt]) =====
|
||||
Equivalent to **eval(raw_input(prompt))**.
|
||||
|
||||
This function does not catch user errors. If the input is not syntactically valid, a SyntaxError will be raised. Other exceptions may be raised if there is an error during evaluation.
|
||||
|
||||
If the __readline__ module was loaded, then input() will use it to provide elaborate line editing and history features.
|
||||
|
||||
Consider using the **raw_input()** function for general input from users.
|
||||
|
||||
===== int(x=0) =====
|
||||
|
||||
===== int(x, base=10) =====
|
||||
Convert a number or string x to an integer, or return 0 if no arguments are given. If x is a number, it can be a plain integer, a long integer, or a floating point number. If x is floating point, the conversion __truncates towards zero__. If the argument is outside the integer range, the function returns a long object instead.
|
||||
|
||||
__如果x为number,则不需要为其指定base参数,因为int函数会根据x的前缀如0b, 0x等正确判断。如果x为float number则其必须为十进制。__
|
||||
|
||||
If x is not a number or if base is given, then x must be a string or Unicode object __representing an integer literal in radix base__.
|
||||
|
||||
__如果x为string,则其必须为整型数字字符串,不能为各种进制的小数字符串。__
|
||||
|
||||
Optionally, the literal can be preceded by + or - (with no space in between) and __surrounded by whitespace__. A base-n literal consists of the digits 0 to n-1, with **a to z (or A to Z)** having values __10 to 35__. The default base is 10. The allowed values are 0 and 2-36.
|
||||
|
||||
Base-2, -8, and -16 literals can be optionally **prefixed with 0b/0B, 0o/0O/0, or 0x/0X**, as with integer literals in code. __Base 0__ means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16.
|
||||
|
||||
The integer type is described in Numeric Types — int, float, long, complex.
|
||||
>>> int("0xfff") **//默认为Base 10, 所以解码错误。**
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
ValueError: invalid literal for int() with __base 10__: '0xfff'
|
||||
>>> int("0xfff", 16)
|
||||
4095
|
||||
>>> int(0xfff.ff) __//如果x为float number,则其必须为十进制。__
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
AttributeError: 'int' object has no attribute 'ff'
|
||||
>>> int(111.22)
|
||||
111
|
||||
>>> int(0b111.11)
|
||||
File "<stdin>", line 1
|
||||
int(0b111.11)
|
||||
^
|
||||
SyntaxError: invalid syntax
|
||||
>>>
|
||||
>>> int("**0xfff.ff"**, 16)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
ValueError: invalid literal for int() with base 16: '0xfff.ff'
|
||||
>>>
|
||||
|
||||
>>> int('22.33') __//如果x为string,则必须为整型数字字符串。__
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
ValueError: invalid literal for int() with base 10: '22.33'
|
||||
|
||||
===== isinstance(object, classinfo) =====
|
||||
Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. Also return true if classinfo is a type object (new-style class) and object is an object of that type or of a (direct, indirect or virtual) subclass thereof. If object is not a class instance or an object of the given type, the function always returns false. If classinfo is neither a class object nor a type object, it may be a tuple of class or type objects, or may recursively contain other such tuples (other sequence types are not accepted). If classinfo is not a class, type, or tuple of classes, types, and such tuples, a TypeError exception is raised.
|
||||
|
||||
Changed in version 2.2: Support for a tuple of type information was added.
|
||||
|
||||
===== issubclass(class, classinfo) =====
|
||||
Return true if class is a subclass (direct, indirect or virtual) of classinfo. A class is considered a subclass of itself. classinfo may be a tuple of class objects, in which case every entry in classinfo will be checked. In any other case, a TypeError exception is raised.
|
||||
|
||||
Changed in version 2.3: Support for a tuple of type information was added.
|
||||
|
||||
===== iter(o[, sentinel]) =====
|
||||
Return an iterator object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, o must be __a collection object__ which supports th**e iteration protocol** (the __iter__() method), or it must support **the sequence protocol** (the __getitem__() method with integer arguments starting at 0). If it does not support either of those protocols, TypeError is raised. If the second argument, sentinel, is given, then o must be __a callable object__. The iterator created in this case will **call o with no arguments for each call** to its next() method; if the value returned is __equal to sentinel__, StopIteration will be raised, otherwise the value will be returned.
|
||||
|
||||
如果没有使用第二个参数,则o必须为容器对象。否则,o必须为可调用对象。
|
||||
|
||||
One useful application of the second form of iter() is to read lines of a file until a certain line is reached. The following example reads a file until the readline() method returns an empty string:
|
||||
|
||||
with open('mydata.txt') as fp:
|
||||
for line in iter(fp.readline, ''):
|
||||
process_line(line)
|
||||
New in version 2.2.
|
||||
|
||||
===== len(s) =====
|
||||
Return the length (the number of items) of an object. The argument may be a sequence (string, tuple or list) or a mapping (dictionary).
|
||||
|
||||
===== list([iterable]) =====
|
||||
Return a list whose items are the same and in the same order as iterable‘s items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, **a copy is made** and returned, similar to iterable[:]. For instance, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, returns a new empty list, [].
|
||||
|
||||
list is a mutable sequence type, as documented in Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange. For other containers see the built in dict, set, and tuple classes, and the collections module.
|
||||
|
||||
===== locals() =====
|
||||
Update and return a dictionary representing the **current local symbol table**. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.
|
||||
|
||||
Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
|
||||
|
||||
===== long(x=0) =====
|
||||
|
||||
===== long(x, base=10) =====
|
||||
Convert a string or number to a long integer. If the argument is a string, it must contain a possibly signed number of arbitrary size, possibly embedded in whitespace. The base argument is interpreted in the same way as for int(), and may only be given when x is a string. Otherwise, the argument may be a plain or long integer or a floating point number, and a long integer with the same value is returned. Conversion of floating point numbers to integers truncates (towards zero). If no arguments are given, returns 0L.
|
||||
|
||||
The long type is described in Numeric Types — int, float, long, complex.
|
||||
|
||||
===== map(function, iterable, ...) =====
|
||||
Apply function to **every item of iterable** and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be __extended with None items__. If function is None, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is __always a list__.
|
||||
|
||||
===== max(iterable[, key]) =====
|
||||
|
||||
===== max(arg1, arg2, *args[, key]) =====
|
||||
Return the largest item in an iterable or the largest of two or more arguments.
|
||||
|
||||
If one positional argument is provided, iterable must be a non-empty iterable (such as a non-empty string, tuple or list). The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned.
|
||||
|
||||
The optional key argument specifies **a one-argument ordering function** like that used for list.sort(). The key argument, if supplied, must be __in keyword form__ (for example, max(a,b,c,key=func)).
|
||||
|
||||
Changed in version 2.5: Added support for the optional key argument.
|
||||
|
||||
===== memoryview(obj) =====
|
||||
Return a “memory view” object created from the given argument. See memoryview type for more information.
|
||||
|
||||
===== min(iterable[, key]) =====
|
||||
|
||||
===== min(arg1, arg2, *args[, key]) =====
|
||||
Return the smallest item in an iterable or the smallest of two or more arguments.
|
||||
|
||||
If one positional argument is provided, iterable must be a non-empty iterable (such as a non-empty string, tuple or list). The smallest item in the iterable is returned. If two or more positional arguments are provided, the smallest of the positional arguments is returned.
|
||||
|
||||
The optional key argument specifies a one-argument ordering function like that used for list.sort(). The key argument, if supplied, __must be in keyword form (__for example, min(a,b,c,key=func)).
|
||||
|
||||
Changed in version 2.5: Added support for the optional key argument.
|
||||
|
||||
===== next(iterator[, default]) =====
|
||||
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
|
||||
|
||||
New in version 2.6.
|
||||
|
||||
===== object() =====
|
||||
Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
Changed in version 2.3: This function does not accept any arguments. Formerly, it accepted arguments but ignored them.
|
||||
|
||||
===== oct(x) =====
|
||||
Convert an integer number (of any size) to an octal string. The result is a valid Python expression.
|
||||
|
||||
Changed in version 2.4: Formerly only returned an unsigned literal.
|
||||
|
||||
===== open(name[, mode[, buffering]]) =====
|
||||
Open a file, returning an object of the **file type** described in section File Objects. If the file cannot be opened, __IOError__ is raised. When opening a file, it’s preferable to use open() instead of invoking the file constructor directly.
|
||||
|
||||
The first two arguments are the same as for stdio‘s fopen(): name is the file name to be opened, and mode is a string indicating how the file is to be opened.
|
||||
|
||||
The most commonly-used values of mode are __'r'__ for reading, __'w'__ for writing (**truncating the file** if it already exists), and __'a'__ for appending (which on some Unix systems means that all writes append to the end of the file regardless of the current seek position). If mode is omitted, __it defaults to 'r'__. The default is to use __text mode__, which may convert '\n' characters to a platform-specific representation on writing and back on reading. Thus, when opening a binary file, you should append __'b'__ to the mode value to open the file in binary mode, which will improve portability. (Appending 'b' is useful even on systems that don’t treat binary and text files differently, where it serves as documentation.) See below for more possible values of mode.
|
||||
|
||||
The optional buffering argument specifies the file’s desired buffer size: __0 means unbuffered, 1 means line buffered, any other positive value means use a buffer of (approximately) that size.__ A negative buffering means to use **the system default**, which is usually line buffered for tty devices and fully buffered for other files. If omitted, the system default is used. [2]
|
||||
|
||||
Modes **'r+', 'w+' and 'a+'** open the file for updating (note that __'w+' truncates the file__). Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don’t have this distinction, adding the 'b' has no effect.
|
||||
|
||||
In addition to the standard **fopen()** values mode may be 'U' or 'rU'. Python is usually built with universal newlines support; supplying 'U' opens the file as a text file, but lines may be terminated by any of the following: the Unix end-of-line convention '\n', the Macintosh convention '\r', or the Windows convention '\r\n'. All of these external representations are seen as '\n' by the Python program. If Python is built without universal newlines support a mode with 'U' is the same as normal text mode. Note that file objects so opened also have an attribute called newlines which has a value of None (if no newlines have yet been seen), '\n', '\r', '\r\n', or a tuple containing all the newline types seen.
|
||||
|
||||
Python enforces that the mode, after stripping 'U', begins with 'r', 'w' or 'a'.
|
||||
|
||||
Python provides many file handling modules including __fileinput, os, os.path, tempfile, and shutil__.
|
||||
|
||||
Changed in version 2.5: Restriction on first letter of mode string introduced.
|
||||
|
||||
===== ord(c) =====
|
||||
Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string. For example, ord('a') returns the integer 97, ord(u'\u2020') returns 8224. This is the inverse of chr() for 8-bit strings and of unichr() for unicode objects. If a unicode argument is given and Python was built with UCS2 Unicode, then the character’s code point must be in the range [0..65535] inclusive; otherwise the string length is two, and a TypeError will be raised.
|
||||
|
||||
===== pow(x, y[, z]) =====
|
||||
Return x to the power y; if z is present, return **x to the power y, modulo z** (computed more efficiently than pow(x, y) % z). The two-argument form pow(x, y) is equivalent to using the power operator: **x**y**.
|
||||
|
||||
The arguments must have numeric types. With mixed operand types, the coercion rules for binary arithmetic operators apply. For int and long int operands, the result has the same type as the operands (after coercion) unless the second argument is negative; in that case, all arguments are converted to float and a float result is delivered. For example, 10**2 returns 100, but 10**-2 returns 0.01. (This last feature was added in Python 2.2. In Python 2.1 and before, if both arguments were of integer types and the second argument was negative, an exception was raised.) If the second argument is negative, the third argument must be omitted. If z is present, x and y must be of integer types, and y must be non-negative. (This restriction was added in Python 2.2. In Python 2.1 and before, floating 3-argument pow() returned platform-dependent results depending on floating-point rounding accidents.)
|
||||
|
||||
===== print(*objects, sep=' ', end='\n', file=sys.stdout) =====
|
||||
|
||||
Print objects to the stream file, separated by sep and followed by end. sep, end and file, if present, must be given as keyword arguments.
|
||||
|
||||
All non-keyword arguments are converted to strings like **str()** does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
|
||||
|
||||
The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Output buffering is determined by file. Use **file.flush()** to ensure, for instance, immediate appearance on a screen.
|
||||
|
||||
Note This function is **not normally available as a built-in** since the name print is recognized as the **print statement**.
|
||||
该函数一般不能直接使用,因为pythn2中的print是一个statement。
|
||||
To disable the statement and use the print() function, use this future statement at the top of your module:
|
||||
__from __future__ import print_function__
|
||||
New in version 2.6.
|
||||
|
||||
===== property([fget[, fset[, fdel[, doc]]]]) =====
|
||||
Return a property attribute for new-style classes (classes that derive from object).
|
||||
|
||||
fget is a function for getting an attribute value, likewise fset is a function for setting, and fdel a function for del’ing, an attribute. Typical use is to define a managed attribute x:
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
def getx(self):
|
||||
return self._x
|
||||
def setx(self, value):
|
||||
self._x = value
|
||||
def delx(self):
|
||||
del self._x
|
||||
__x = property(getx, setx, delx, "I'm the 'x' property.")__
|
||||
If then c is an instance of C, **c.x will invoke the getter, c.x = value will invoke the setter and del c.x the deleter**.
|
||||
|
||||
If given, doc will be the docstring of the property attribute(例如上面的最后一行字符串). Otherwise, the property will copy fget‘s docstring (if it exists). This makes it possible to create **read-only properties** easily using property() as a decorator:
|
||||
|
||||
class Parrot(object):
|
||||
def __init__(self):
|
||||
self._voltage = 100000
|
||||
|
||||
__@property //生成一个read-only properity。__
|
||||
def voltage(self):
|
||||
"""Get the current voltage."""
|
||||
return self._voltage
|
||||
turns the voltage() method into a “getter” for a read-only attribute with the same name.
|
||||
|
||||
A property object has __getter, setter, and deleter__ methods usable as decorators that create a copy of the property with the corresponding accessor function set to the decorated function. This is best explained with an example:
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property //property装饰器使修饰的函数x变为property object,默认生成一个read-only properity。
|
||||
def x(self):
|
||||
"""I'm the 'x' property."""
|
||||
return self._x
|
||||
|
||||
__@x__.setter //调用property object的setter方法。
|
||||
__def x__(self, value):
|
||||
self._x = value
|
||||
|
||||
@x.deleter
|
||||
def x(self): //注意没有参数,x就暗示了属性的类型。
|
||||
del self._x
|
||||
This code is exactly equivalent to the first example. Be sure to give the additional functions **the same name as the original** property (x in this case.)
|
||||
|
||||
The returned property also has the attributes fget, fset, and fdel corresponding to the constructor arguments.
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
Changed in version 2.5: Use fget‘s docstring if no doc given.
|
||||
|
||||
Changed in version 2.6: The getter, setter, and deleter attributes were added.
|
||||
|
||||
===== range(stop) =====
|
||||
|
||||
===== range(start, stop[, step]) =====
|
||||
This is a versatile function to create lists containing arithmetic progressions. It is most often used in __for loops__. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised). Example:
|
||||
|
||||
>>>
|
||||
>>> range(10)
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> range(1, 11)
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
>>> range(0, 30, 5)
|
||||
[0, 5, 10, 15, 20, 25]
|
||||
>>> range(0, 10, 3)
|
||||
[0, 3, 6, 9]
|
||||
>>> range(0, -10, -1)
|
||||
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
|
||||
>>> range(0)
|
||||
[]
|
||||
>>> range(1, 0)
|
||||
[]
|
||||
|
||||
===== raw_input([prompt]) =====
|
||||
If the prompt argument is present, it is written to standard output __without a trailing newline__. The function then reads a line from input, __converts it to a string (stripping a trailing newline)__, and returns that. When EOF is read, EOFError is raised. Example:
|
||||
|
||||
>>>
|
||||
>>> s = raw_input('--> ')
|
||||
--> Monty Python's Flying Circus
|
||||
>>> s
|
||||
"Monty Python's Flying Circus"
|
||||
If the readline module was loaded, then raw_input() will use it to provide elaborate line editing and history features.
|
||||
|
||||
===== reduce(function, iterable[, initializer]) =====
|
||||
Apply function of __two arguments__ cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). **The left argument, x, is the **__accumulated value__** and the right argument, y, is the update value from the iterable**. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned. Roughly equivalent to:
|
||||
|
||||
def reduce(function, iterable, initializer=None):
|
||||
it = iter(iterable)
|
||||
if initializer is None:
|
||||
try:
|
||||
initializer = next(it)
|
||||
except StopIteration:
|
||||
raise TypeError('reduce() of empty sequence with no initial value')
|
||||
**accum_value** = initializer
|
||||
for x in it:
|
||||
accum_value = function(accum_value, x)
|
||||
return accum_value
|
||||
|
||||
===== reload(module) =====
|
||||
Reload a previously imported module. The argument must be **a module object**, so it must have been successfully imported before. This is useful if you have **edited the module source file** using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the module object (the same as the module argument).
|
||||
|
||||
When reload(module) is executed:
|
||||
|
||||
Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called a second time.
|
||||
As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
|
||||
The names in the module namespace are updated to point to any new or changed objects.
|
||||
Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.
|
||||
|
||||
There are a number of other caveats:
|
||||
|
||||
If a module is syntactically correct but its initialization fails, the first import statement for it does not bind its name locally, but does store a (partially initialized) module object in sys.modules. To reload the module you must first import it again (this will bind the name to the partially initialized module object) before you can reload() it.
|
||||
|
||||
When a module is reloaded, its dictionary (containing the module’s global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem. If the new version of a module does not define a name that was defined by the old version, the old definition remains. This feature can be used to the module’s advantage if it maintains a global table or cache of objects — with a try statement it can test for the table’s presence and skip its initialization if desired:
|
||||
|
||||
try:
|
||||
cache
|
||||
except NameError:
|
||||
cache = {}
|
||||
It is legal though generally not very useful to reload built-in or dynamically loaded modules, except for sys, __main__ and __builtin__. In many cases, however, extension modules are not designed to be initialized more than once, and may fail in arbitrary ways when reloaded.
|
||||
|
||||
If a module imports objects from another module using from ... import ..., calling reload() for the other module does not redefine the objects imported from it — one way around this is to re-execute the from statement, another is to use import and qualified names (module.*name*) instead.
|
||||
|
||||
If a module instantiates instances of a class, reloading the module that defines the class does not affect the method definitions of the instances — they continue to use the old class definition. The same is true for derived classes.
|
||||
|
||||
===== repr(object) =====
|
||||
Return a string containing **a printable representation of an object**. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.
|
||||
|
||||
===== reversed(seq) =====
|
||||
__Return a reverse iterator.__ seq must be an object which has a __reversed__() method or supports **the sequence protocol** (the __len__() method and the __getitem__() method with integer arguments starting at 0).
|
||||
|
||||
New in version 2.4.
|
||||
|
||||
Changed in version 2.6: Added the possibility to write a custom __reversed__() method.
|
||||
|
||||
===== round(number[, ndigits]) =====
|
||||
Return the floating point value number rounded to **ndigits digits after the decimal point.** If ndigits is omitted, it defaults to zero. The result is a floating point number. Values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done away from 0 (so. for example, round(0.5) is 1.0 and round(-0.5) is -1.0).
|
||||
|
||||
Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
|
||||
|
||||
===== set([iterable]) =====
|
||||
Return a new set object, optionally with elements taken from iterable. set is a built-in class. See set and Set Types — set, frozenset for documentation about this class.
|
||||
|
||||
For other containers see the built-in frozenset, list, tuple, and dict classes, as well as the collections module.
|
||||
|
||||
New in version 2.4.
|
||||
|
||||
===== setattr(object, name, value) =====
|
||||
This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. For example, setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.
|
||||
|
||||
===== slice(stop) =====
|
||||
|
||||
===== slice(start, stop[, step]) =====
|
||||
Return a slice object representing the set of indices specified by **range(start, stop, step)**. The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default). They have no other explicit functionality; however they are used by Numerical Python and other third party extensions. Slice objects are also generated when extended indexing syntax is used. For example: a[start:stop:step] or a[start:stop, i]. See itertools.islice() for an alternate version that returns an iterator.
|
||||
|
||||
===== sorted(iterable[, cmp[, key[, reverse]]]) =====
|
||||
Return __a new sorted list__ from the items in iterable.
|
||||
|
||||
The optional arguments **cmp, key, and reverse** have the same meaning as those for the list.sort() method (described in section Mutable Sequence Types).
|
||||
|
||||
cmp specifies __a custom comparison function of two arguments__ (iterable elements) which should __return a negative, zero or positive number__ depending on whether the first argument is considered smaller than, equal to, or larger than the second argument: cmp=lambda x,y: cmp(x.lower(), y.lower()). The default value is None.
|
||||
|
||||
key specifies a function of one argument that is used to **extract a comparison key from each list element**: key=str.lower. The default value is None (compare the elements directly).
|
||||
|
||||
reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.
|
||||
|
||||
In general, the key and reverse conversion processes are much faster than specifying an equivalent cmp function. This is because cmp is called multiple times for each list element while key and reverse touch each element only once. Use **functools.cmp_to_key()** to convert an old-style cmp function to a key function.
|
||||
|
||||
For sorting examples and a brief sorting tutorial, see Sorting HowTo.
|
||||
|
||||
New in version 2.4.
|
||||
|
||||
===== staticmethod(function) =====
|
||||
Return a static method for function.
|
||||
|
||||
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
|
||||
|
||||
class C:
|
||||
@staticmethod
|
||||
def f(arg1, arg2, ...): ...
|
||||
The @staticmethod form is a function decorator – see the description of function definitions in Function definitions for details.
|
||||
|
||||
It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.
|
||||
|
||||
Static methods in Python are similar to those found in Java or C++. Also see classmethod() for a variant that is useful for creating alternate class constructors.
|
||||
|
||||
For more information on static methods, consult the documentation on the standard type hierarchy in The standard type hierarchy.
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
Changed in version 2.4: Function decorator syntax added.
|
||||
|
||||
===== str(object='') =====
|
||||
Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with repr(object) is that str(object) does not always attempt to return a string that is acceptable to eval(); its goal is to return a printable string. If no argument is given, returns the empty string, ''.
|
||||
|
||||
For more information on strings see Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange which describes sequence functionality (strings are sequences), and also the string-specific methods described in the String Methods section. To output formatted strings use template strings or the % operator described in the String Formatting Operations section. In addition see the String Services section. See also unicode().
|
||||
|
||||
===== sum(iterable[, start]) =====
|
||||
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterable‘s items are normally numbers, and the start value is not allowed to be a string.
|
||||
|
||||
For some use cases, there are good alternatives to sum(). The preferred, fast way to concatenate a sequence of strings is by calling __''.join(sequence)__. To add floating point values with extended precision, see math.fsum(). To concatenate a series of iterables, consider using itertools.chain().
|
||||
|
||||
New in version 2.3.
|
||||
|
||||
===== super(type[, object-or-type]) =====
|
||||
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
|
||||
|
||||
The ____mro____ attribute of the type lists **the method resolution search order** used by both getattr() and super(). The attribute is dynamic and can change whenever the inheritance hierarchy is updated.
|
||||
|
||||
If the second argument is omitted, the super object returned is unbound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods).
|
||||
|
||||
Note super() only works for new-style classes.
|
||||
There are two typical use cases for super. In a class hierarchy with single inheritance, **super can be used to refer to parent classes **__without naming them explicitly__, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.
|
||||
|
||||
The second use case is to support __cooperative multiple inheritance in a dynamic execution environment__. This use case is unique to Python and is not found in statically compiled languages or languages that only support single inheritance. This makes it possible to implement “diamond diagrams” where multiple base classes implement the same method. Good design dictates that this method have the same calling signature in every case (because the order of calls is determined at runtime, because that order adapts to changes in the class hierarchy, and because that order can include sibling classes that are unknown prior to runtime).
|
||||
|
||||
For both use cases, a typical superclass call looks like this:
|
||||
|
||||
class C(B):
|
||||
def method(self, arg):
|
||||
super(C, self).method(arg)
|
||||
Note that super() is implemented as part of the binding process for explicit dotted attribute lookups such as super().__getitem__(name). It does so by implementing its own __getattribute__() method for searching classes in a predictable order that supports cooperative multiple inheritance. Accordingly, super() is undefined for implicit lookups using statements or operators such as super()[name].
|
||||
|
||||
Also note that super() is not limited to use inside methods. The two argument form specifies the arguments exactly and makes the appropriate references.
|
||||
|
||||
For practical suggestions on how to design cooperative classes using super(), see guide to using super().
|
||||
|
||||
New in version 2.2.
|
||||
|
||||
===== tuple([iterable]) =====
|
||||
Return a tuple whose items are the same and in the same order as iterable‘s items. iterable may be a sequence, a container that supports iteration, or an iterator object. If iterable is already a tuple, it is returned unchanged. For instance, tuple('abc') returns ('a', 'b', 'c') and tuple([1, 2, 3]) returns (1, 2, 3). If no argument is given, returns a new empty tuple, ().
|
||||
|
||||
tuple is an immutable sequence type, as documented in Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange. For other containers see the built in dict, list, and set classes, and the collections module.
|
||||
|
||||
===== type(object) =====
|
||||
|
||||
===== type(name, bases, dict) =====
|
||||
With one argument, return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.
|
||||
|
||||
With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the __name__ attribute; the bases tuple itemizes the base classes and becomes the __bases__ attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the __dict__ attribute. For example, the following two statements create identical type objects:
|
||||
|
||||
>>>
|
||||
>>> class X(object):
|
||||
... a = 1
|
||||
...
|
||||
>>> X = type('X', (object,), dict(a=1))
|
||||
New in version 2.2.
|
||||
|
||||
===== unichr(i) =====
|
||||
Return the Unicode string of one character whose Unicode code is the integer i. For example, unichr(97) returns the string u'a'. This is the inverse of ord() for Unicode strings. The valid range for the argument depends how Python was configured – it may be either UCS2 [0..0xFFFF] or UCS4 [0..0x10FFFF]. ValueError is raised otherwise. For ASCII and 8-bit strings see chr().
|
||||
|
||||
New in version 2.0.
|
||||
|
||||
===== unicode(object='') =====
|
||||
|
||||
===== unicode(object[, encoding[, errors]]) =====
|
||||
Return the Unicode string version of object using one of the following modes:
|
||||
|
||||
If encoding and/or errors are given, unicode() will decode the object which can either be an 8-bit string or a character buffer using the codec for encoding. The encoding parameter is a string giving the name of an encoding; if the encoding is not known, LookupError is raised. Error handling is done according to errors; this specifies the treatment of characters which are invalid in the input encoding. If errors is 'strict' (the default), a ValueError is raised on errors, while a value of 'ignore' causes errors to be silently ignored, and a value of 'replace' causes the official Unicode replacement character, U+FFFD, to be used to replace input characters which cannot be decoded. See also the codecs module.
|
||||
|
||||
If no optional parameters are given, unicode() will mimic the behaviour of str() except that it returns Unicode strings instead of 8-bit strings. More precisely, if object is a Unicode string or subclass it will return that Unicode string without any additional decoding applied.
|
||||
|
||||
For objects which provide a __unicode__() method, it will call this method without arguments to create a Unicode string. For all other objects, the 8-bit string version or representation is requested and then converted to a Unicode string using the codec for the default encoding in 'strict' mode.
|
||||
|
||||
For more information on Unicode strings see Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange which describes sequence functionality (Unicode strings are sequences), and also the string-specific methods described in the String Methods section. To output formatted strings use template strings or the % operator described in the String Formatting Operations section. In addition see the String Services section. See also str().
|
||||
|
||||
New in version 2.0.
|
||||
|
||||
Changed in version 2.2: Support for __unicode__() added.
|
||||
|
||||
===== vars([object]) =====
|
||||
Return the __dict__ attribute for a module, class, instance, or any other object with a __dict__ attribute.
|
||||
|
||||
Objects such as modules and instances have an updateable __dict__ attribute; however, other objects may have write restrictions on their __dict__ attributes (for example, new-style classes use a dictproxy to prevent direct dictionary updates).
|
||||
|
||||
Without an argument, vars() acts like locals(). Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.
|
||||
|
||||
===== xrange(stop) =====
|
||||
|
||||
===== xrange(start, stop[, step]) =====
|
||||
This function is very similar to range(), but returns an xrange object instead of a list. This is an opaque sequence type which yields the same values as the corresponding list, without actually storing them all simultaneously. The advantage of xrange() over range() is minimal (since xrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the range’s elements are never used (such as when the loop is usually terminated with break). For more information on xrange objects, see XRange Type and Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange.
|
||||
|
||||
CPython implementation detail: xrange() is intended to be simple and fast. Implementations may impose restrictions to achieve this. The C implementation of Python restricts all arguments to native C longs (“short” Python integers), and also requires that the number of elements fit in a native C long. If a larger range is needed, an alternate version can be crafted using the itertools module: islice(count(start, step), (stop-start+step-1+2*(step<0))//step).
|
||||
|
||||
===== zip([iterable, ...]) =====
|
||||
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.
|
||||
|
||||
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n).
|
||||
|
||||
zip() in conjunction with the * operator can be used to unzip a list:
|
||||
|
||||
>>>
|
||||
>>> x = [1, 2, 3]
|
||||
>>> y = [4, 5, 6]
|
||||
>>> zipped = zip(x, y)
|
||||
>>> zipped
|
||||
[(1, 4), (2, 5), (3, 6)]
|
||||
>>> x2, y2 = zip(*zipped)
|
||||
>>> x == list(x2) and y == list(y2)
|
||||
True
|
||||
New in version 2.0.
|
||||
|
||||
Changed in version 2.4: Formerly, zip() required at least one argument and zip() raised a TypeError instead of returning an empty list.
|
||||
|
||||
===== __import__(name[, globals[, locals[, fromlist[, level]]]]) =====
|
||||
Note This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().
|
||||
This function is invoked by the import statement. It can be replaced (by importing the __builtin__ module and assigning to __builtin__.__import__) in order to change semantics of the import statement, but nowadays it is usually simpler to use import hooks (see PEP 302). Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.
|
||||
|
||||
The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name. The standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.
|
||||
|
||||
level specifies whether to use absolute or relative imports. The default is -1 which indicates both absolute and relative imports will be attempted. 0 means only perform absolute imports. Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__().
|
||||
|
||||
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.
|
||||
|
||||
For example, the statement import spam results in bytecode resembling the following code:
|
||||
|
||||
spam = __import__('spam', globals(), locals(), [], -1)
|
||||
The statement import spam.ham results in this call:
|
||||
|
||||
spam = __import__('spam.ham', globals(), locals(), [], -1)
|
||||
Note how __import__() returns the toplevel module here because this is the object that is bound to a name by the import statement.
|
||||
|
||||
On the other hand, the statement from spam.ham import eggs, sausage as saus results in
|
||||
|
||||
_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
|
||||
eggs = _temp.eggs
|
||||
saus = _temp.sausage
|
||||
Here, the spam.ham module is returned from __import__(). From this object, the names to import are retrieved and assigned to their respective names.
|
||||
|
||||
If you simply want to import a module (potentially within a package) by name, use importlib.import_module().
|
||||
|
||||
Changed in version 2.5: The level parameter was added.
|
||||
|
||||
Changed in version 2.5: Keyword support for parameters was added.
|
||||
|
||||
===== 3. Non-essential Built-in Functions =====
|
||||
There are several built-in functions that are no longer essential to learn, know or use in modern Python programming. They have been kept here to maintain backwards compatibility with programs written for older versions of Python.
|
||||
|
||||
Python programmers, trainers, students and book writers should feel free to bypass these functions without concerns about missing something important.
|
||||
|
||||
apply(function, args[, keywords])
|
||||
The function argument must be a callable object (a user-defined or built-in function or method, or a class object) and the args argument must be a sequence. The function is called with args as the argument list; the number of arguments is the length of the tuple. If the optional keywords argument is present, it must be a dictionary whose keys are strings. It specifies keyword arguments to be added to the end of the argument list. Calling apply() is different from just calling function(args), since in that case there is always exactly one argument. The use of apply() is equivalent to function(*args, **keywords).
|
||||
|
||||
Deprecated since version 2.3: Use function(*args, **keywords) instead of apply(function, args, keywords) (see Unpacking Argument Lists).
|
||||
|
||||
buffer(object[, offset[, size]])
|
||||
The object argument must be an object that supports the buffer call interface (such as strings, arrays, and buffers). A new buffer object will be created which references the object argument. The buffer object will be a slice from the beginning of object (or from the specified offset). The slice will extend to the end of object (or will have a length given by the size argument).
|
||||
|
||||
coerce(x, y)
|
||||
Return a tuple consisting of the two numeric arguments converted to a common type, using the same rules as used by arithmetic operations. If coercion is not possible, raise TypeError.
|
||||
|
||||
intern(string)
|
||||
Enter string in the table of “interned” strings and return the interned string – which is string itself or a copy. Interning strings is useful to gain a little performance on dictionary lookup – if the keys in a dictionary are interned, and the lookup key is interned, the key comparisons (after hashing) can be done by a pointer compare instead of a string compare. Normally, the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys.
|
||||
|
||||
Changed in version 2.3: Interned strings are not immortal (like they used to be in Python 2.2 and before); you must keep a reference to the return value of intern() around to benefit from it.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] It is used relatively rarely so does not warrant being made into a statement.
|
||||
[2] Specifying a buffer size currently has no effect on systems that don’t have setvbuf(). The interface to specify the buffer size is not done using a method that calls setvbuf(), because that may dump core when called after any I/O has been performed, and there’s no reliable way to determine whether this is the case.
|
||||
[3] In the current implementation, local variable bindings cannot normally be affected this way, but variables retrieved from other scopes (such as modules) can be. This may change.
|
||||
»
|
||||
indexmodules |next |previous | Python » Documentation » The Python Standard Library »
|
||||
© Copyright 1990-2012, Python Software Foundation.
|
||||
The Python Software Foundation is a non-profit corporation. Please donate.
|
||||
Last updated on Dec 01, 2012. Found a bug?
|
||||
Created using Sphinx 1.0.7.
|
||||
@@ -0,0 +1,57 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-02T20:49:44+08:00
|
||||
|
||||
====== 4. Built-in Constants ======
|
||||
Created Sunday 02 December 2012
|
||||
|
||||
A small number of constants live in the built-in namespace. They are:
|
||||
|
||||
===== False =====
|
||||
The false value of the bool type.
|
||||
|
||||
New in version 2.3.
|
||||
|
||||
===== True =====
|
||||
The true value of the bool type.
|
||||
|
||||
New in version 2.3.
|
||||
|
||||
===== None =====
|
||||
The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function.
|
||||
|
||||
Changed in version 2.4: Assignments to None are illegal and raise a SyntaxError.
|
||||
|
||||
===== NotImplemented =====
|
||||
Special value which can be returned by the “rich comparison” special methods (__eq__(), __lt__(), and friends), to indicate that the comparison is not implemented with respect to the other type.
|
||||
|
||||
===== Ellipsis =====
|
||||
Special value used in conjunction with extended slicing syntax.
|
||||
|
||||
===== __debug__ =====
|
||||
This constant is true if Python was __not started with an -O option__. See also the assert statement.
|
||||
|
||||
Note The names None and __debug__ cannot be reassigned (assignments to them, even as an attribute name, raise SyntaxError), so they can be considered “true” constants.
|
||||
Changed in version 2.7: Assignments to __debug__ as an attribute became illegal.
|
||||
|
||||
===== 4.1. Constants added by the site module =====
|
||||
The site module (which is __imported automatically during startup__, except if the -S command-line option is given) adds several constants to the built-in namespace. They are useful for the interactive interpreter shell and should not be used in programs.
|
||||
|
||||
===== quit([code=None]) =====
|
||||
|
||||
===== exit([code=None]) =====
|
||||
Objects that when printed, print a message like “Use quit() or Ctrl-D (i.e. EOF) to exit”, and when called, raise SystemExit with the specified exit code.
|
||||
|
||||
==== copyright ====
|
||||
|
||||
==== license ====
|
||||
|
||||
==== credits ====
|
||||
Objects that when printed, print a message like “Type license() to see the full license text”, and when called, display the corresponding text in a pager-like fashion (one screen at a time).
|
||||
|
||||
»
|
||||
indexmodules |next |previous | Python » Documentation » The Python Standard Library »
|
||||
© Copyright 1990-2012, Python Software Foundation.
|
||||
The Python Software Foundation is a non-profit corporation. Please donate.
|
||||
Last updated on Dec 02, 2012. Found a bug?
|
||||
Created using Sphinx 1.0.7.
|
||||
38
Zim/Programme/python/The-Python-Standard-Library/int.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-02T10:31:10+08:00
|
||||
|
||||
====== int ======
|
||||
Created Sunday 02 December 2012
|
||||
|
||||
|
||||
In [12]: lst = '123\n' //如果字符串中包含__空字符(如空格, \t, \v, \f, \n, \r)等__,int(), float()等函数仍然有效。
|
||||
In [13]: lst
|
||||
Out[13]: '123\n'
|
||||
|
||||
__In [14]: int(lst)__
|
||||
__Out[14]: 123__
|
||||
|
||||
In [15]: lst = '123\n\t'
|
||||
|
||||
In [16]: lst
|
||||
Out[16]: '123\n\t'
|
||||
|
||||
In [18]: int(lst)
|
||||
Out[18]: 123
|
||||
|
||||
|
||||
In [19]: lst = '123\nstr' //字符串中包含除了数字外的非空字符,转换时提示错误。
|
||||
|
||||
In [20]: lst
|
||||
Out[20]: '123\nstr'
|
||||
|
||||
In [21]: int(lst)
|
||||
---------------------------------------------------------------------------
|
||||
ValueError Traceback (most recent call last)
|
||||
<ipython-input-21-7fdf78d62dad> in <module>()
|
||||
----> 1 int(lst)
|
||||
|
||||
__ValueError:__ invalid literal for int() with **base 10**: '123\nstr'
|
||||
|
||||
In [22]:
|
||||
74
Zim/Programme/python/The-Python-Standard-Library/list.txt
Normal file
@@ -0,0 +1,74 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-02T09:40:06+08:00
|
||||
|
||||
====== list ======
|
||||
Created Sunday 02 December 2012
|
||||
|
||||
~ $ ipython2
|
||||
Python 2.7.3 (default, Apr 24 2012, 00:06:13)
|
||||
Type "copyright", "credits" or "license" for more information.
|
||||
|
||||
In [1]: lst = ['sdfds', 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']]
|
||||
|
||||
__In [2]: lst[0]=[1, 2, 3] //为列表的某个成员赋值时,python不会对右边的值进行迭代。__
|
||||
|
||||
In [3]: lst
|
||||
Out[3]: 1, 2, 3], 'dsfsd', 1, 3, [123, 22, 33, 'dsfds'
|
||||
|
||||
__In [8]: lst[0:0] = 'dffds' //为列表的成员列表赋值时,python会对右边的值进行迭代。__
|
||||
|
||||
In [9]: lst
|
||||
Out[9]: [__'d', 'f', 'f', 'd', 's',__ 'dffds', 2, 3, 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']] //可见,python对等式右边序列进行了迭代。
|
||||
|
||||
In [4]: lst[0:1] = [1, 2, 3]
|
||||
|
||||
In [5]: lst
|
||||
Out[5]: [1, 2, 3, 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']] //同上
|
||||
|
||||
In [10]:
|
||||
|
||||
__In [10]: lst[0:0] = ['dffds'] //将字符序列外加[和]就可以阻止迭代(因为这时字符串时列表的唯一成员)__
|
||||
|
||||
In [11]: lst
|
||||
Out[11]:
|
||||
['dffds',
|
||||
'd',
|
||||
'f',
|
||||
'f',
|
||||
'd',
|
||||
's',
|
||||
'dffds',
|
||||
2,
|
||||
3,
|
||||
'dsfsd',
|
||||
1,
|
||||
3,
|
||||
[123, 22, 33, 'dsfds']]
|
||||
|
||||
In [12]:
|
||||
|
||||
In [24]: lst
|
||||
Out[24]: '123\nstr'
|
||||
|
||||
In [25]: lst = [1, 2, 3]
|
||||
|
||||
In [26]: lst = lst + [4, 5, 6] //列表相+时,python会对第二个列表进行__迭代__。
|
||||
|
||||
In [27]: lst
|
||||
Out[27]: [1, 2, 3, **4, 5, 6]**
|
||||
|
||||
__In [28]: lst = lst + 'fdf' //只能list间相加__
|
||||
---------------------------------------------------------------------------
|
||||
TypeError Traceback (most recent call last)
|
||||
<ipython-input-28-0818686a3a7d> in <module>()
|
||||
----> 1 lst = lst + 'fdf'
|
||||
|
||||
TypeError: **can only concatenate list** (not "str") to list
|
||||
|
||||
In [29]: lst = lst + list('fdf')
|
||||
|
||||
In [30]: lst
|
||||
Out[30]: [1, 2, 3, 4, 5, 6, 'f', 'd', 'f']
|
||||
|
||||
In [31]:
|
||||
@@ -6,10 +6,6 @@ Creation-Date: 2012-01-05T15:16:44+08:00
|
||||
Created Thursday 05 January 2012
|
||||
http://www.noah.org/wiki/Pexpect
|
||||
|
||||
pexpect
|
||||
(Redirected from Pexpect)
|
||||
|
||||
|
||||
Contents
|
||||
|
||||
1 Pexpect version 2.3
|
||||
@@ -59,22 +55,12 @@ Download the current version here from the SourceForge site here: pexpect curren
|
||||
===== Description of Pexpect =====
|
||||
|
||||
Pexpect is a **pure Python module** that makes Python a better tool for__ controlling and automating other programs__. Pexpect is similar to the Don Libes `Expect` system, but Pexpect as a different interface that is easier to understand.
|
||||
|
||||
Pexpect is__ basically a pattern matching system__. It runs programs and watches output. When output matches a given pattern Pexpect can **respond** as if a human were typing responses. Pexpect can be used for** automation, testing, and screen scraping**.
|
||||
Pexpect can be used for__ automating interactive console applications __such as ssh, ftp, passwd, telnet, etc.
|
||||
It can also be used to__ control web applications__ via `lynx`, `w3m`, or some other **text-based **web browser. Pexpect is pure Python. Unlike other Expect-like modules for Python Pexpect does not require TCL or Expect nor does it require C extensions to be compiled. It should work on any platform that supports the standard Python pty module.
|
||||
|
||||
Pexpect can be used for__ automating interactive console applications __such as ssh, ftp, passwd, telnet, etc. It can also be used to__ control web applications__ via `lynx`, `w3m`, or some other **text-based **web browser. Pexpect is pure Python. Unlike other Expect-like modules for Python Pexpect does not require TCL or Expect nor does it require C extensions to be compiled. It should work on any platform that supports the standard Python __pty__ module.
|
||||
|
||||
Send questions to: noah@noah.org Put 'pexpect' in the subject.
|
||||
License
|
||||
|
||||
MIT style -- Free, open source, and all that good stuff.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Pexpect Copyright (c) 2010 Noah Spurrier
|
||||
|
||||
===== Download and Installation =====
|
||||
|
||||
1045
Zim/Programme/python/The-Python-Standard-Library/re.txt
Normal file
@@ -0,0 +1,92 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-30T20:55:38+08:00
|
||||
|
||||
====== string的操作函数 ======
|
||||
Created Friday 30 November 2012
|
||||
|
||||
转自:http://www.91linux.com/html/article/program/python/20090804/17759.htm
|
||||
|
||||
在python有各种各样的string操作函数。在历史上string类在python中经历了一段轮回的历史。在最开始的时候,python有**一个专门的string的module**,要使用string的方法要先import,但后来由于众多的python使用者的建议,从python2.0开始,string方法改为用S.method()的形式调用,只要S是一个字符串对象就可以这样使用,而不用import。同时__为了保持向后兼容__,现在的python中仍然保留了一个string的module,其中定义的方法与S.method()是相同的,这些方法都**最后都指向了**用S.method()调用的函数。要注意,S.method()能调用的方法比string的module中的多,比如isdigit()、istitle()等就只能用S.method()的方式调用。
|
||||
|
||||
对一个字符串对象,首先想到的操作可能就是计算它有多少个字符组成,很容易想到用S.len(),但这是错的,应该是__len(S)__。因为len()是内置函数,包括在__builtin__模块中。python不把len()包含在string类型中,乍看起来好像有点不可理解,其实一切有其合理的逻辑在里头。len()不仅可以计算字符串中的字符数,还可以计算list的成员数,tuple的成员数等等,因此**单单把len()算在string里是不合适**,因此一是可以__把len()作为通用函数__,用重载实现对不同类型的操作,还有就是可以在每种有len()运算的类型中都要包含一个len()函数。python选择的是第一种解决办法。类似的还有str(arg)函数,它把arg用string类型表示出来。
|
||||
|
||||
===== 字符串中字符大小写的变换: =====
|
||||
S.lower() #小写
|
||||
S.upper() #大写
|
||||
S.swapcase() #大小写互换
|
||||
S.capitalize() #首字母大写
|
||||
String.capwords(S)
|
||||
#这是模块中的方法。它把S用split()函数分开,然后用capitalize()把首字母变成大写,最后用join()合并到一起
|
||||
S.title() #只有首字母大写,其余为小写,模块中没有这个方法
|
||||
|
||||
===== 字符串在输出时的对齐: =====
|
||||
S.ljust(width,[fillchar])
|
||||
#输出width个字符,S左对齐,不足部分用fillchar填充,默认的为空格。
|
||||
S.rjust(width,[fillchar]) #右对齐
|
||||
S.center(width, [fillchar]) #中间对齐
|
||||
S.zfill(width) #把S变成width长,并在右对齐,不足部分用0补足
|
||||
|
||||
===== 字符串中的搜索和替换: =====
|
||||
S.find(substr, [start, [end]])
|
||||
#返回S中出现substr的第一个字母的标号,如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索
|
||||
S.index(substr, [start, [end]])
|
||||
#与find()相同,只是在S中没有substr时,会返回一个运行时错误
|
||||
S.rfind(substr, [start, [end]])
|
||||
#返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号
|
||||
S.rindex(substr, [start, [end]])
|
||||
S.count(substr, [start, [end]]) #计算substr在S中出现的次数
|
||||
S.replace(oldstr, newstr, [count])
|
||||
#把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换
|
||||
S.strip([chars])
|
||||
#把S中前后chars中有的字符全部去掉,可以理解为把S前后chars替换为None
|
||||
S.lstrip([chars])
|
||||
S.rstrip([chars])
|
||||
S.expandtabs([tabsize])
|
||||
#把S中的tab字符替换没空格,每个tab替换为tabsize个空格,默认是8个
|
||||
|
||||
===== 字符串的分割和组合: =====
|
||||
S.split([sep, [maxsplit]])
|
||||
#以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符
|
||||
S.rsplit([sep, [maxsplit]])
|
||||
S.splitlines([keepends])
|
||||
#把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。
|
||||
S.join(seq) #把seq代表的序列──字符串序列,用S连接起来
|
||||
|
||||
|
||||
|
||||
===== 字符串的mapping,这一功能包含两个函数: =====
|
||||
String.maketrans(from, to)
|
||||
#返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。
|
||||
S.translate(table[,deletechars])
|
||||
#使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果S为unicode字符串,那么就不支持deletechars参数,可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。
|
||||
|
||||
===== 字符串还有一对编码和解码的函数: =====
|
||||
S.encode([encoding,[errors]])
|
||||
#其中encoding可以有多种值,比如gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默认值为"strict",意思是UnicodeError。可能的值还有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和所有的通过codecs.register_error注册的值。这一部分内容涉及codecs模块,不是特明白
|
||||
|
||||
S.decode([encoding,[errors]])
|
||||
|
||||
===== 字符串的测试函数,这一类函数在string模块中没有,这些函数返回的都是bool值: =====
|
||||
|
||||
S.startwith(prefix[,start[,end]])
|
||||
#是否以prefix开头
|
||||
S.endwith(suffix[,start[,end]])
|
||||
#以suffix结尾
|
||||
S.isalnum()
|
||||
#是否全是字母和数字,并至少有一个字符
|
||||
S.isalpha() #是否全是字母,并至少有一个字符
|
||||
S.isdigit() #是否全是数字,并至少有一个字符
|
||||
S.isspace() #是否全是空白字符,并至少有一个字符
|
||||
S.islower() #S中的字母是否全是小写
|
||||
S.isupper() #S中的字母是否便是大写
|
||||
S.istitle() #S是否是首字母大写的
|
||||
|
||||
===== 字符串类型转换函数,这几个函数只在string模块中有: =====
|
||||
|
||||
**string.atoi(s[,base])**
|
||||
#base默认为10,如果为0,那么s就可以是012或0x23这种形式的字符串,如果是16那么s就只能是0x23或0X12这种形式的字符串
|
||||
string.atol(s[,base]) #转成long
|
||||
string.atof(s[,base]) #转成float
|
||||
|
||||
这里再强调一次,字符串对象是不可改变的,也就是说在python创建一个字符串后,你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后,都会返回一个__新的字符串__,原字串并没有变。其实这也是有变通的办法的,__可以用S=list(S)这个函数把S变为由单个字符为成员的list,这样的话就可以使用S[3]='a'的方式改变值,然后再使用S=" ".join(S)还原成字符串__
|
||||
@@ -39,13 +39,13 @@ __subprocess.STDOUT__
|
||||
|
||||
[*] subprocess.__call__(**args**, *, stdin=None, stdout=None, stderr=None, shell=False)
|
||||
Run the command described by __args__. __Wait __for command to complete, then return the **returncode** attribute.
|
||||
适合非交互式进程,执行args指定的程序直到其结束,返回退出码,即使命令执行失败,也不产生异常。stdin,stdout,stderr一般不使用PIPE,因为调用进程一般不读这种非交互式进程的输出。stdin为None表示子进程的stdin将__继承__调用进程的描述符。
|
||||
适合非交互式进程,执行args指定的程序直到其结束,返回退出码,即使命令执行失败,也不产生异常。stdin,stdout,stderr一般不使用PIPE,因为调用进程一般不读这种非交互式进程的输出。stdin为None表示子进程的stdin将__继承__调用进程的描述符。
|
||||
|
||||
The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the slightly odd notation in the abbreviated signature). The full function signature is the same as that of the __Popen__ constructor - this functions passes all supplied arguments directly through to that interface.
|
||||
|
||||
Examples:
|
||||
>>>
|
||||
__#如果shell=False(默认),则python调用os.execlp()来执行args,因此,如果args是字符串,则只能包含命令名;如果是序列,则可以包含命令参数(参数不支持shell的特性如文件名扩展等。),而且每个元素一般包括一个参数(否则调用程序可能会产生解析错误)。__
|
||||
__#如果shell=False(默认),则python调用os.exelp()来执行args,因此,如果args是字符串,则只能包含命令名;如果是序列,则可以包含命令参数(参数不支持shell的特性如文件名扩展等。)。__
|
||||
>>> subprocess.call(__["ls", "-l"]__)
|
||||
0
|
||||
__#如果shell=True,则python调用system shell来执行args,调用形式为: execlp("/bin/sh", '-c', 'arg1', 'arg2', ....)因此,如果args是字符串,则其中可以包含命令参数,而且支持各种shell特性如文件名扩展、命令扩展等;如果args是序列,则其第一个元素为命令名,其它元素为被当作shell本身的参数。__
|
||||
@@ -53,14 +53,14 @@ __#如果shell=True,则python调用system shell来执行args,调用形式为
|
||||
>>> subprocess.call("exit 1", shell=True)
|
||||
1
|
||||
|
||||
__总的来说__**:**如果shell=False, python使用os.execvp(...)来执行args,因此,如果args是一个string,则该string只能是命令名称, 如果要为命令附加参数,则只能使用序列类型; 如果shell=True,则python使用shell来执行行args,因此,args最好是一个string,该string可以包含命令名及其参数,如果使用序列,则从第二个元素开始作为shell本身的参数(而非命令的参数。)。
|
||||
__总的来说__**:**如果shell=False, python使用os.execvp(...)来执行args,因此,如果args是一个string,则该string__只能是__命令名称, 如果要为命令附加参数,则只能使用序列类型; 如果shell=True,则python使用shell来执行行args,因此,args最好是一个string,该string可以包含命令名及其参数,如果使用序列,则从第二个元素开始作为shell本身的参数(而非命令的参数。)。
|
||||
|
||||
Invoking the system shell with shell=True can be **a security hazard** if combined with untrusted input. See the warning under Frequently Used Arguments for details.
|
||||
|
||||
__Do not use stdout=PIPE or stderr=PIPE with this function__. As the pipes are not being read in the current process, the child process may block if it generates enough output to a pipe to fill up the OS pipe buffer.
|
||||
当使用stdout=PIPE时,如果子进程填满了管道而调用进程没有读该管道时__子进程就会被阻塞__。因此使用上面三个函数时一般不使用这个参数。
|
||||
|
||||
The standard input and output channels for the process started by call() are__ bound to the parent’s input and output__. That means the calling programm cannot capture the output of the command. Use check_output() to capture the output for later processing.
|
||||
The standard input and output channels for the process started by call() are__ bound to the parent’s input and output__. That means the calling programm __cannot capture the output__ of the command. Use check_output() to capture the output for later processing.
|
||||
|
||||
[*] subprocess.**check_call**(args, *, stdin=None, stdout=None, stderr=None, shell=False)
|
||||
和call类似,但是对返回值进行检查,如果非0则引发异常。
|
||||
@@ -152,9 +152,10 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
|
||||
|
||||
Arguments are:
|
||||
|
||||
* args should be a string, or a sequence of program arguments. The program to execute is normally the **first item** in the args sequence or the string if a string is given, but can be **explicitly set **by using the __executable__ argument. When executable is given, the first item in the args sequence is still treated by most programs as the** command name**, which can then be different from the actual executable name. On Unix, it becomes the** display name** for the executing program in utilities such as ps.
|
||||
* args should be a string, or a sequence of program arguments. The program to execute is normally the **first item** in the args sequence or the string(string作为命令名,不能有参数) if a string is given, but can be **explicitly set **by using the __executable__ argument. When executable is given, the first item in the args sequence is still treated by most programs as the** command name**, which can then be different from the actual executable name. On Unix, it becomes the** display name** for the executing program in utilities such as ps. 如果ecutable被设置,则其值将作为__实际执行__的命令名。args的第一个元素将作为命令的显示名称。
|
||||
|
||||
On Unix, with shell=False (default): In this case, the __Popen class uses os.execvp()__ to execute the child program. args should **normally be a sequence.** If a string is specified for args, it will be used as the **name or path of the program **to execute; this will only work if the program is being given __no__ arguments.
|
||||
默认情况下shell=False,这样args通常为sequence,其第一个元素为待执行的命令,其它元素为命令参数。如果args为string,则其**只能为命令名或命令路径,不能带任何参数**。这时因为python使用os.execvp()来执行这个string。
|
||||
|
||||
Note
|
||||
|
||||
@@ -172,22 +173,22 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
|
||||
Note in particular that options (such as -input) and arguments (such as eggs.txt) that are separated by whitespace in the shell go in **separate list elements**, while arguments that need quoting or backslash escaping when used in the shell (such as filenames containing spaces or the echo command shown above) are single list elements.
|
||||
|
||||
On Unix, with shell=True: __If args is a string, it specifies the command string to execute through the shell.__ This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments __to the shell itself__. That is to say, Popen does the equivalent of:
|
||||
在shell=True的情况下,args最好是一个字符串。如果是序列,则从第二个元素开始是__作为shell本身的参数__,而非命令的参数。
|
||||
在shell=True的情况下,args**最好是一个字符串**。如果是序列,则从第二个元素开始是__作为shell本身的参数__,而非命令的参数。
|
||||
__ Popen(['/bin/sh', '-c', args[0], args[1], ...])__
|
||||
|
||||
On Windows: the Popen class uses CreateProcess() to execute the child child program, which __operates on strings.__ If args is a sequence, it will be converted to a string in a manner described in Converting an argument sequence to a string on Windows.
|
||||
|
||||
**总的来说:如果shell=False, python使用os.execvp(...)来执行args,因此,如果args是一个string,则该string只能是命令名称, 如果要为命令执行参数,则只能使用序列类型; 如果shell=True,则python使用shell来执行行args,因此,args最好是一个string,该string可以包含命令名及其参数,如果使用序列,则从第二个元素开始作为**__shell本身__**的参数(而非命令的参数。)。**
|
||||
|
||||
* bufsize, if given, has the same meaning as the corresponding argument to the built-in open() function: **0 means **__unbuffered__**, 1 means**__ line buffered__**, any other positive value means use a buffer of (approximately) that size**. A negative bufsize means to use the system **default**, which usually means__ fully__ buffered. The** default value for bufsize is 0** (unbuffered).
|
||||
控制打开文件的缓冲方式。
|
||||
* bufsize, if given, has the same meaning as the corresponding argument to the built-in open() function: **0 means **__unbuffered__**, 1 means**__ line buffered__**, any other positive value means use a buffer of (approximately) that size**. A negative bufsize means to use the system **default**, which usually means__ fully__ buffered. The** default value for bufsize is 0** __(unbuffered)__.
|
||||
控制打开文件的缓冲方式,默认为unbuffered。
|
||||
|
||||
Note
|
||||
If you experience performance issues, it is recommended that you try to enable buffering by setting bufsize to either -1 or a large enough positive value (such as 4096).
|
||||
|
||||
* The executable argument **specifies the program** to execute. It is very seldom needed: Usually, the program to execute is defined by the **args** argument. If shell=True, the executable argument specifies __which shell to use__. On Unix, the default shell is /bin/sh. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.
|
||||
* The executable argument **specifies the program** to execute. It is very seldom needed: Usually, the program to execute is defined by the **args** argument. If shell=True, the executable argument specifies __which shell to use__. On Unix, the default shell is **/bin/sh**. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.
|
||||
|
||||
* stdin, stdout and stderr specify the __executed program’s __standard input, standard output and standard error file handles, respectively. Valid values are __PIPE, an existing file descriptor (a positive integer), an existing file object, and None__. PIPE indicates that a new pipe to the child should be created. With the **default settings of None**, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.
|
||||
* stdin, stdout and stderr specify the __executed program’s __standard input, standard output and standard error file handles, respectively. Valid values are __PIPE, an existing file descriptor (a positive integer), an existing file object, and None__. PIPE indicates that a new pipe to the child should be created. With the **default settings of None**, no redirection will occur; the child’s file handles will be **inherited from the parent**. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.
|
||||
|
||||
* If__ preexec_fn__ is set to a callable object, this object will be called in the child process just **before** the child is executed. (Unix only)
|
||||
|
||||
@@ -210,7 +211,8 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
|
||||
Note
|
||||
This feature is only available if Python is built with universal newline support (the default). Also, the newlines attribute of the file objects stdout, stdin and stderr are not updated by the communicate() method.
|
||||
|
||||
* If given, startupinfo will be a STARTUPINFO object, which is passed to the underlying __CreateProcess __function. creationflags, if given, can be CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP. (Windows only)
|
||||
* If given, startupinfo will be a STARTUPINFO object, which is passed to the underlying __CreateProcess __function.
|
||||
* creationflags, if given, can be CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP. (Windows only)?
|
||||
|
||||
==== 17.1.1.3. Exceptions ====
|
||||
|
||||
@@ -232,11 +234,11 @@ Popen()函数返回一个__Popen对象__。
|
||||
Instances of the Popen class have the following methods:
|
||||
|
||||
**Popen.poll()**
|
||||
Check if child process __has terminated__. Set and return returncode attribute.
|
||||
Check if child process __has terminated__. Set and return **returncode** attribute.
|
||||
|
||||
**Popen.wait()**
|
||||
|
||||
Wait for child process to terminate. Set and return returncode attribute.
|
||||
Wait for child process to terminate. Set and return **returncode** attribute.
|
||||
|
||||
Warning
|
||||
This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.
|
||||
@@ -247,7 +249,7 @@ __Popen.communicate__(input=None)
|
||||
|
||||
communicate() returns __a tuple__ (stdoutdata, stderrdata).
|
||||
|
||||
Note that if you want to send data to the process’s stdin, you need to create the Popen object with__ stdin=PIPE__. Similarly, to get anything other than None in the result tuple, you need to give__ stdout=PIPE__ and/or stderr=PIPE too.
|
||||
Note that if you want to send data to the process’s stdin, you need to create the Popen object with__ stdin=PIPE__. Similarly, to get anything other than None in the result tuple, you need to give__ stdout=PIPE__ and/or __stderr=PIPE__ too.
|
||||
|
||||
Note
|
||||
The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
|
||||
@@ -262,7 +264,7 @@ __Popen.communicate__(input=None)
|
||||
|
||||
**Popen.terminate()**
|
||||
|
||||
Stop the child. On Posix OSs the method sends SIGTERM to the child. On Windows the Win32 API function TerminateProcess() is called to stop the child.
|
||||
Stop the child. On Posix OSs the method sends __SIGTERM__ to the child. On Windows the Win32 API function TerminateProcess() is called to stop the child.
|
||||
|
||||
**Popen.kill()**
|
||||
|
||||
@@ -271,7 +273,7 @@ __Popen.communicate__(input=None)
|
||||
===== The following attributes are also available: =====
|
||||
**Popen对象**具有下列属性:
|
||||
Warning
|
||||
Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.
|
||||
Use communicate() rather than //.stdin.write, .stdout.read or .stderr.read// to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.
|
||||
|
||||
Popen.stdin #对Popen调用stdin属性,将返回一个**写打开的文件对象**。
|
||||
If the stdin argument was PIPE, this attribute is **a file object** that provides input to the child process. Otherwise, it is__ None__.
|
||||
@@ -287,7 +289,7 @@ Popen.__pid__
|
||||
|
||||
Popen.__returncode__
|
||||
|
||||
The child return code, **set by poll() and wait()** (and indirectly by communicate()). A __None__ value indicates that the process hasn’t terminated yet. A negative value -N indicates that the child was **terminated by signal N** (Unix only).
|
||||
The child return code, **set by poll() and wait()** (and indirectly by communicate()). A __None__ value indicates that the process hasn’t terminated yet. A negative value __-N__ indicates that the child was **terminated by signal N** (Unix only).
|
||||
|
||||
|
||||
===== 17.1.3.1. Constants =====
|
||||
@@ -314,7 +316,7 @@ subprocess.STARTF_USESHOWWINDOW
|
||||
|
||||
subprocess.CREATE_NEW_CONSOLE
|
||||
|
||||
The new process ha**s a new console**, instead of inheriting its parent’s console (the default).
|
||||
The new process ha**s a new console**, instead of inheriting its parent’s console __(the default)__.
|
||||
This flag is always set when Popen is created with shell=True.
|
||||
|
||||
subprocess.CREATE_NEW_PROCESS_GROUP
|
||||
@@ -345,12 +347,20 @@ output=`dmesg | grep hda`
|
||||
# becomes
|
||||
p1 = Popen(["dmesg"], __stdout=PIPE__)
|
||||
p2 = Popen(["grep", "hda"], stdin=__p1.stdout__, stdout=PIPE) #p1是Popen对象,其stdout返回一个读打开的文件对象(因为p1的stdout为PIPE)。
|
||||
__p1.stdout__.close() # Allow p1 to receive a SIGPIPE if p2 exits.
|
||||
__p1.stdout__.close() # Allow p1 to receive a SIGPIPE if p2 exits,**关键!!!**
|
||||
output = __p2.communicate()__[0] #communicate()返回一个__元组__,这里只取出第一个元素即子进程的标准输出。
|
||||
|
||||
The p1.stdout.close() call after starting the p2 is __important in order__ for p1 to receive a SIGPIPE if p2 exits before p1.
|
||||
具体解释如下:stackoverflow.com/q/7391689
|
||||
From Wikipedia, SIGPIPE is the signal sent to a process when it attempts to **write** to a pipe without a process connected to the other end.
|
||||
|
||||
When you first create p1 using **stdout=PIPE**, there is one process connected to the pipe, which is __your Python process__, and you can read the output using p1.stdout.
|
||||
最开始Popen()时,python解释器会连接到p1.stdout管道,这样在p2没有创建前,p1的cmd就可以执行了,输出将临时地放入管道中。
|
||||
When you create p2 using stdin=p1.stdout there are now __two processes__ connected to the pipe p1.stdout.
|
||||
|
||||
Generally when you are running processes in a pipeline you want **all processes** to end when any of the processes end. For this to happen automatically __you need to close p1.stdout so p2.stdin is the only process attached to that pipe__, this way if p2 ends and p1 writes additional data to stdout, it will receive a SIGPIPE since there are no longer any processes attached to that pipe.
|
||||
|
||||
Alternatively, for trusted input, the shell’s own pipeline support may still be used directly:
|
||||
Alternatively, for **trusted input**, the shell’s own pipeline support may still be used directly:
|
||||
|
||||
output=`dmesg | grep hda` # becomes output=__check_output__(“dmesg | grep hda”,__ shell=True__)
|
||||
|
||||
@@ -432,7 +442,7 @@ p = Popen("cmd", shell=True, bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, __stderr=STDOUT__, close_fds=True) #STDOUT标示,子进程的标准出错和__它的__标准输出__重定向到同一个__文件。
|
||||
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
|
||||
|
||||
On Unix, os.popen2, os.popen3 and os.popen4 also accept __a sequence__ as the command to execute, in which case arguments will be passed directly to the program without shell intervention. This usage can be replaced as follows:
|
||||
On Unix, os.popen2, os.popen3 and os.popen4 also accept __a sequence__ as the command to execute, in which case arguments will be passed **directly to the program** without shell intervention. This usage can be replaced as follows:
|
||||
|
||||
(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
|
||||
bufsize)
|
||||
@@ -444,13 +454,13 @@ Return code handling translates as follows:
|
||||
|
||||
pipe = os.popen("cmd", 'w')
|
||||
...
|
||||
rc = pipe.close()
|
||||
if rc is not None and rc >> 8:
|
||||
rc = pipe.close() //"cmd"进程读管道时收到EOF,程序一般将终止。
|
||||
if rc is not None and rc **>> 8**:
|
||||
print "There were some errors"
|
||||
==>
|
||||
process = Popen("cmd", 'w', shell=True, stdin=PIPE)
|
||||
...
|
||||
process.stdin.close()
|
||||
process.stdin.close() //**同样使'cmd'读到EOF**,而自动终止。
|
||||
if **process.wait()** != 0:
|
||||
print "There were some errors"
|
||||
|
||||
@@ -473,19 +483,19 @@ p = Popen(["mycmd", "myarg"], bufsize=bufsize,
|
||||
|
||||
popen2.Popen3 and popen2.Popen4 basically work as subprocess.Popen, except that:
|
||||
|
||||
Popen raises an exception if the execution fails.
|
||||
the capturestderr argument is replaced with the stderr argument.
|
||||
stdin=PIPE and stdout=PIPE must be specified.
|
||||
popen2 closes all file descriptors by default, but you have to specify close_fds=True with Popen.
|
||||
* Popen raises an exception if the execution fails.
|
||||
* the capturestderr argument is replaced with the stderr argument.
|
||||
* stdin=PIPE and stdout=PIPE must be specified.
|
||||
* popen2 closes all file descriptors by default, but you have to specify close_fds=True with Popen.
|
||||
|
||||
===== 17.1.5. Notes =====
|
||||
17.1.5.1. Converting an argument sequence to a string on Windows
|
||||
|
||||
On Windows, an args sequence is converted to a string that can be parsed using the following rules (which correspond to the rules used by the MS C runtime):
|
||||
|
||||
Arguments are delimited by white space, which is either a space or a tab.
|
||||
A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
|
||||
A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
|
||||
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
|
||||
If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule 3.
|
||||
* Arguments are delimited by white space, which is either a space or a tab.
|
||||
* A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
|
||||
* A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
|
||||
* Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
|
||||
* If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule 3.
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -38,7 +38,7 @@ The interpreter acts as a simple calculator: you can type an expression at it an
|
||||
>>> #__ Integer division returns the floor__:
|
||||
... 7/3
|
||||
2
|
||||
>>> 7/-3
|
||||
>>> 7/-3 //对于整型出发,结果也是整数,而且结果总是rounded towards minus infinity。也就是说__结果总是取小于小数的最大整数值。__例如7/-3= -2.25...,而小于-2.25的最大整数为-3.
|
||||
-3
|
||||
|
||||
The equal sign ('=') is used to assign a value to a variable. Afterwards, no result is displayed before the next interactive prompt:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-05T15:16:40+08:00
|
||||
|
||||
====== library ======
|
||||
Created Thursday 05 January 2012
|
||||
|
||||
@@ -13,7 +13,7 @@ class dict(object)
|
||||
| (key, value) pairs
|
||||
| dict(iterable) -> new dictionary initialized as if via:
|
||||
| d = {}
|
||||
| for **k, v** in iterable: #迭代器对象每次返回的元素必须是一个容器类型,__容器中元素的个数为2__.**如[a,b], "ab",(a,b)**
|
||||
| for **k, v** in iterable: #迭代器对象每次返回的元素必须是一个容器类型,__容器中元素的个数为2__.**如[a,b], **~~"ab"~~**,(a,b)**
|
||||
| d[k] = v
|
||||
| dict(__**kwargs)__ -> new dictionary initialized with the name=value pairs
|
||||
| in the keyword argument list. For example: dict(one=1, two=2)
|
||||
|
||||
@@ -36,3 +36,39 @@ unpack一个顺序容器类型时,左边变量的数目必须要与容器中
|
||||
>>> print k,v
|
||||
d f
|
||||
>>>
|
||||
|
||||
In [9]: for k,v in 'dfdf': //对于字符串的迭代,迭代其每次只返回__一个字符__,所以赋值给k,v时出错
|
||||
...: print k,v
|
||||
...:
|
||||
---------------------------------------------------------------------------
|
||||
ValueError Traceback (most recent call last)
|
||||
<ipython-input-9-5ba17a6181e2> in <module>()
|
||||
----> 1 for k,v in 'dfdf':
|
||||
2 print k,v
|
||||
3
|
||||
|
||||
ValueError: need more than 1 value to unpack
|
||||
|
||||
In [10]: k,v='ff' __//对于可迭代对象,展开后的元素个数必须与等式左边的相等。__
|
||||
|
||||
In [11]: print k,v
|
||||
**f f**
|
||||
In [13]: k,v='fff'
|
||||
---------------------------------------------------------------------------
|
||||
ValueError Traceback (most recent call last)
|
||||
<ipython-input-13-0aecd2a10b05> in <module>()
|
||||
----> 1 k,v='fff'
|
||||
|
||||
ValueError: too many values to unpack
|
||||
|
||||
In [14]:
|
||||
In [12]:
|
||||
|
||||
In [12]: for k,v in ['df',[1,2],(3,4)]: __//每次迭代器返回列表中的一个元素,每个元素都可以展开为2个变量。__
|
||||
print k,v
|
||||
....:
|
||||
d f
|
||||
1 2
|
||||
3 4
|
||||
|
||||
In [13]:
|
||||
|
||||
130
Zim/Utils/gdb/gdb_debugging.txt
Normal file
@@ -0,0 +1,130 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T16:49:56+08:00
|
||||
|
||||
====== gdb debugging ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
[geekard@geekard elf]$ **gdb demo**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
**(gdb) info source **//查看当前使用的source file name
|
||||
|
||||
|
||||
**(gdb) info args **
|
||||
name = 0x80486a3 "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff920
|
||||
**(gdb) info locals**
|
||||
a = -1209680176
|
||||
nm = 0xbffff914 "\027"
|
||||
fr = {0xbffff948 "",
|
||||
0xb7e5beff <printf+47> "\203\304\030[\303f\220f\220f\220f\220f\220f\220S\203\354\030\215D$,\211D$\f\213D$(讷\r",
|
||||
0xb7fb5a00 <_IO_2_1_stdout_> "\204*\255", <incomplete sequence \373>, 0x80486b4 "\tThe globalVarStatic is:%d\n"}
|
||||
//从上面两次的反汇编结果可以得出如下结论:
|
||||
//1. break function-name 设置的断点并不位于function的入口处,而break *function-name才是。
|
||||
//2. break function-name设置的断点位于function的prologue指令之后,auto variable初始化指令之前。
|
||||
//3. 当执行到前面设置的断点时,函数的args已经由caller通过stack传入,但是函数的auto variable还没有被初始化
|
||||
|
||||
**(gdb) bt **//查看函数调用信息,即backtrap。callee的编号小于其caller。
|
||||
#0 greeting (name=0x80486a3 "geekard", age=23, friends=0xbffff920) at demo.c:13
|
||||
#1 0x08048578 in main (argc=5, argv=0xbffff9e4) at demo.c:50
|
||||
**(gdb) info f 1 **//查看stack frame编号为1的函数帧信息
|
||||
Stack frame at 0xbffff950:
|
||||
eip = 0x8048578 in main (demo.c:50); saved eip 0xb7e28605
|
||||
caller of frame at 0xbffff910
|
||||
source language c.
|
||||
Arglist at 0xbffff948, args: argc=5, argv=0xbffff9e4
|
||||
Locals at 0xbffff948, Previous frame's sp is 0xbffff950
|
||||
Saved registers:
|
||||
ebp at 0xbffff948, eip at 0xbffff94c
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0x804842c in greeting (demo.c:13); saved eip 0x8048578
|
||||
called by frame at 0xbffff950
|
||||
source language c.
|
||||
Arglist at 0xbffff908, args: name=0x80486a3 "geekard", age=23, friends=0xbffff920
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers:
|
||||
eip at 0xbffff90c
|
||||
**(gdb) disassemble main **//反汇编main函数
|
||||
Dump of assembler code for function main:
|
||||
//从info f 1的输出可知,call main前esp的值为 0xbffff950。
|
||||
0x080484f0 <+0>: push %ebp
|
||||
0x080484f1 <+1>: mov %esp,%ebp //main函数的prologue指令,break main时停止在下一条指令处。
|
||||
0x080484f3 <+3>: and $0xfffffff0,%esp //SystemV i386 ABI规定esp必须word对齐。
|
||||
0x080484f6 <+6>: sub $0x30,%esp //为main的auto variables预留空间,此后esp的值为0xbffff10。
|
||||
|
||||
0x080484f9 <+9>: mov 0x8049918,%eax
|
||||
0x080484fe <+14>: mov %eax,0x2c(%esp) //int autoVar = globVar;
|
||||
|
||||
0x08048502 <+18>: mov 0x8049924,%eax
|
||||
0x08048507 <+23>: mov %eax,0x28(%esp) //i = externVar;
|
||||
|
||||
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) // char *name = "geekard"
|
||||
|
||||
0x08048513 <+35>: movl $0x17,0x20(%esp) // int age = 23
|
||||
|
||||
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //"Tom"
|
||||
0x08048523 <+51>: movl $0x804863d,0x14(%esp) //"John"
|
||||
0x0804852b <+59>: movl $0x8048642,0x18(%esp) //"Pi"
|
||||
0x08048533 <+67>: movl $0x0,0x1c(%esp) //NULL
|
||||
//char **friends = {x, x, NUU},friends是一个指向字符指针的指针__变量(占有内存单元)__,其指向的数组有4个元素。
|
||||
//变量friends的地址为0xbffff918,即0x8($esp)处,可以用print &friends命令打印出。
|
||||
//变量friends的值为0xbffff920,指向栈上"Tom"所在的内参单元地址。对于指针数组变量friends,有以下调试信息:
|
||||
**(gdb) p &friends **
|
||||
$21 = (char ***) 0xbffff918
|
||||
**(gdb) p friends**
|
||||
$17 = (char **) 0xbffff920
|
||||
**(gdb) p friends@4**
|
||||
$18 = {0xbffff920, 0x80485f2 <__libc_csu_init+82>, 0x8048639, 0x804863d}
|
||||
**(gdb) p *friends@4**
|
||||
$19 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
|
||||
**(gdb) x /4wx friends@4**
|
||||
0xbffff918: 0xbffff920 0x080485f2 0x08048639 0x0804863d
|
||||
**(gdb) x /4wx *friends@4**
|
||||
0xbffff920: 0x08048639 0x0804863d 0x08048642 0x00000000
|
||||
**(gdb) p *friends@4**
|
||||
$20 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
|
||||
//从main函数的auto variable初始化指令可以得出如下结论:
|
||||
//1. main函数的auto variable是保存在stack中,其layourt的顺序与定义的顺序一致,即先定义的变量先入栈。
|
||||
//2.static variable定义在全局数据段(.data section)中,而不是stack中(int static staticVar并没有在stack中初始化)。
|
||||
//3.数组的各元素入栈顺序与定义顺序相反,即索引越大越先入栈; 指针数组变量最后入栈。
|
||||
|
||||
//auto variable初始化完成后的main栈分配如下:
|
||||
{{./stack.png?height=544}}
|
||||
|
||||
|
||||
0x0804853b <+75>: movl $0x80486ab,(%esp)
|
||||
0x08048542 <+82>: call 0x8048300 <puts@plt>
|
||||
0x08048547 <+87>: mov 0x804991c,%eax
|
||||
0x0804854c <+92>: mov %eax,0x4(%esp)
|
||||
0x08048550 <+96>: movl $0x80486b4,(%esp)
|
||||
0x08048557 <+103>: call 0x80482f0 <printf@plt>
|
||||
0x0804855c <+108>: lea 0x10(%esp),%eax
|
||||
0x08048560 <+112>: mov %eax,0x8(%esp)
|
||||
0x08048564 <+116>: mov 0x20(%esp),%eax
|
||||
0x08048568 <+120>: mov %eax,0x4(%esp)
|
||||
0x0804856c <+124>: mov 0x24(%esp),%eax
|
||||
0x08048570 <+128>: mov %eax,(%esp)
|
||||
0x08048573 <+131>: call 0x804842c <greeting>
|
||||
__0x08048578__ <+136>: movl $0x3,0x4(%esp)
|
||||
0x08048580 <+144>: movl $0x2,(%esp)
|
||||
0x08048587 <+151>: call 0x8048590 <add>
|
||||
0x0804858c <+156>: leave
|
||||
0x0804858d <+157>: ret
|
||||
End of assembler dump.
|
||||
|
||||
//greeting函数的argumets是由main函数通过栈传入的。下面代码节选至main函数的反汇编输出。
|
||||
//函数的auto variable是保存在其stack中的。下面时main函数的auto variable初始化代码。
|
||||
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) //name
|
||||
0x08048513 <+35>: movl $0x17,0x20(%esp) //age
|
||||
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //friends
|
||||
//将greeting函数的friends参数圧入栈中,注意friends参数的值是main的auto variable,所以它保存在main的stack frame中。
|
||||
0x0804855c <+108>: lea 0x10(%esp),%eax
|
||||
0x08048560 <+112>: mov %eax,0x8(%esp) //frinnds
|
||||
0x08048564 <+116>: mov 0x20(%esp),%eax
|
||||
0x08048568 <+120>: mov %eax,0x4(%esp) //通过栈传入age参数
|
||||
0x0804856c <+124>: mov 0x24(%esp),%eax
|
||||
0x08048570 <+128>: mov %eax,(%esp) //通过栈传入name参数
|
||||
0x08048573 <+131>: call 0x804842c <greeting>
|
||||
174
Zim/Utils/gdb/gdb_debugging/gdb_demo.txt
Normal file
@@ -0,0 +1,174 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T22:10:21+08:00
|
||||
|
||||
====== gdb demo ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
[geekard@geekard elf]$ **cat demo.c**
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int globalVar = 1;
|
||||
int globalVarUninit;
|
||||
|
||||
static int globalVarStatic = 3;
|
||||
|
||||
extern int externVar;
|
||||
extern int add(int, int);
|
||||
|
||||
void greeting(char *name, int age, char** friends)
|
||||
{
|
||||
|
||||
int a = 23;
|
||||
char *nm = "zhangjun";
|
||||
char *fr[] = {"Tom", "John", "Pi", NULL}; //fr为__数组名称__,它指向一块内存单元,但是本身不咱用内存单元。
|
||||
char **fr = {"Tom", "John", "Pi", NULL}; //fr为__指针变量,指向一个保存有4个字符指针的内存单元(位于greeting的栈中)。__
|
||||
|
||||
if (name == NULL)
|
||||
name = nm;
|
||||
if (age == 0)
|
||||
age = a;
|
||||
if (friends == NULL)
|
||||
friends = fr;
|
||||
|
||||
printf("In greeting:\n");
|
||||
printf("\tHello, %s:\n", name);
|
||||
printf("\tYourt age is:%d.\n", age);
|
||||
printf("\tYourt friends are:\n");
|
||||
while (*friends != NULL) {
|
||||
printf("\t\t%s\n", *friends);
|
||||
friends += 1;
|
||||
}
|
||||
|
||||
printf("Goodbye from greeting.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int autoVar = globalVar;
|
||||
static int staticVar = 2;
|
||||
int i = externVar;
|
||||
|
||||
char *name = "geekard";
|
||||
int age = 23;
|
||||
char *friends[] = {"Tom", "John", "Pi", NULL};
|
||||
|
||||
printf("In main:\n");
|
||||
printf("\tThe globalVarStatic is:%d\n",globalVarStatic);
|
||||
greeting(name, age, friends);
|
||||
add(2, 3);
|
||||
}
|
||||
[geekard@geekard elf]$ **cat foo.c**
|
||||
int externVar = 1;
|
||||
int static staticVarStatic = 2;
|
||||
|
||||
int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
[geekard@geekard elf]$ **gcc -g demo.c foo.c -o demo**
|
||||
demo.c: In function ‘greeting’:
|
||||
demo.c:18:3: warning: initialization from incompatible pointer type [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
[geekard@geekard elf]$ **gdb demo**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
。。。。。。
|
||||
**(gdb) info source**
|
||||
Current source file is demo.c
|
||||
Compilation directory is /home/geekard/Code/elf
|
||||
Located in /home/geekard/Code/elf/demo.c
|
||||
Contains 53 lines.
|
||||
Source language is c.
|
||||
Compiled with DWARF 2 debugging format.
|
||||
Does not include preprocessor macro info.
|
||||
**(gdb) info sources**
|
||||
Source files for which symbols have been read in:
|
||||
|
||||
/home/geekard/Code/elf/demo.c
|
||||
|
||||
Source files for which symbols will be read in on demand:
|
||||
|
||||
/home/geekard/Code/elf/foo.c
|
||||
|
||||
**(gdb) set args -a aa --bb=bbb ccc ** //设置dmo程序的默认命令行参数,执行run命令时会传入该参数。
|
||||
**(gdb) show args **//查看demo程序的命令行参数
|
||||
Argument list to give program being debugged when it is started is "-a aa --bb=bbb ccc".
|
||||
**(gdb) info args ** //查看当前stack frame对应函数的参数列表信息。
|
||||
No frame selected.
|
||||
(gdb) show env
|
||||
XDG_VTNR=1
|
||||
。。。。。
|
||||
**(gdb) shell clear ** //执行shell命令,这里为clear。
|
||||
**(gdb) info address greeting** //在symbol table中查找greeting函数的入口地址
|
||||
Symbol "greeting" is a function at address 0x804842c.
|
||||
**(gdb) b 0x804842c //在某个地址处设置断点时,地址前应该加星号,否则gdb认为它为函数名称。**
|
||||
Function "0x804842c" not defined.
|
||||
Make breakpoint pending on future shared library load? (y or [n]) n
|
||||
**(gdb) b *0x804842c **
|
||||
Breakpoint 1 at 0x804842c: file demo.c, line 13.
|
||||
**(gdb) b *greeting**
|
||||
Note: breakpoint 1 also set at pc 0x804842c.
|
||||
Breakpoint 2 at 0x804842c: file demo.c, line 13.
|
||||
**(gdb) b greeting** //在greeting函数入口处设一个断点
|
||||
Breakpoint 3 at 0x8048432: file demo.c, line 15.
|
||||
**(gdb) info b**
|
||||
Num Type Disp Enb Address What
|
||||
1 breakpoint keep y 0x0804842c in greeting at demo.c:13
|
||||
2 breakpoint keep y 0x0804842c in greeting at demo.c:13
|
||||
3 breakpoint keep y 0x08048432 in greeting at demo.c:15
|
||||
**(gdb) delete 2 //删除编号为2的断点**
|
||||
**(gdb) list 12,16 //查看当前文件的12至16行。**
|
||||
12 void greeting(char *name, int age, char** friends)
|
||||
13 {
|
||||
14
|
||||
15 int a = 23;
|
||||
16 char *nm = "zhangjun";
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/demo -a aa --bb=bbb ccc //gdb将set args命令的参数传给demo。
|
||||
Breakpoint 1, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:13
|
||||
13 {
|
||||
**(gdb) disassemble greeting** //反汇编greeting函数。如果disassmble没有参数,则默认反汇编当前所执行的函数。
|
||||
Dump of assembler code for function greeting:
|
||||
=> 0x0804842c <+0>: push %ebp //demo停止在greeting函数的入口处,函数的prologue指令还没有执行。
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x28,%esp
|
||||
(gdb) c //继续执行,直到下一个断点处。
|
||||
Continuing.
|
||||
|
||||
Breakpoint 3, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:15
|
||||
15 int a = 23;
|
||||
**(gdb) disassemble** //反汇编当前执行的函数
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x28,%esp
|
||||
=> 0x08048432 <+6>: movl $0x17,-0xc(%ebp) //指令前的"=>"表示下一条**待执行**的指令位置。
|
||||
//可见greeting的prologue指令已经执行,这意味着greeting的栈帧已经建立。但是greeting的auto variable初始化指令还没有执行。
|
||||
0x08048439 <+13>: movl $0x8048620,-0x10(%ebp)
|
||||
0x08048440 <+20>: movl $0x8048629,-0x14(%ebp)
|
||||
0x08048447 <+27>: cmpl $0x0,0x8(%ebp)
|
||||
0x0804844b <+31>: jne 0x8048453 <greeting+39>
|
||||
0x0804844d <+33>: mov -0x10(%ebp),%eax
|
||||
0x08048450 <+36>: mov %eax,0x8(%ebp)
|
||||
。。。。。
|
||||
**(gdb) info args //查看当前stack frame对应函数的参数列表。**
|
||||
name = 0x804868b "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff950 //传经来的时指针
|
||||
**(gdb) info locals** //greeting函数的auto variables还没有初始化,所以下列为无效值
|
||||
a = -1209680176
|
||||
nm = 0xbffff944 "\027"
|
||||
fr = 0x80486a4 //
|
||||
(gdb)
|
||||
|
||||
|
||||
|
||||
|
||||
82
Zim/Utils/gdb/gdb_debugging/gdb_pointer.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T21:45:29+08:00
|
||||
|
||||
====== gdb pointer ======
|
||||
Created Tuesday 25 December 2012
|
||||
[geekard@geekard elf]$ **cat array.c**
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ia[3] = {1,2,3};
|
||||
char *cpa[3] = {"Tom", "John", NULL};
|
||||
char *cpa2[] = {"Tom", "John", NULL};
|
||||
char **cpa3 = {"Tom", "John", NULL};
|
||||
}
|
||||
[geekard@geekard elf]$ **gcc -g array.c -o array**
|
||||
array.c: In function ‘main’:
|
||||
array.c:9:4: warning: initialization from incompatible pointer type [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
[geekard@geekard elf]$ **gdb array**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
。。。。。
|
||||
**(gdb) list main**
|
||||
1 #include <stdio.h>
|
||||
2 #include <stdlib.h>
|
||||
3
|
||||
4 int main(void)
|
||||
5 {
|
||||
6 int ia[3] = {1,2,3};
|
||||
7 char *cpa[3] = {"Tom", "John", NULL};
|
||||
8 char *cpa2[] = {"Tom", "John", NULL}; //ia, cpa, cpa2为数组首地址的引用名称,而非变量,不占用
|
||||
9 char **cpa3 = {"Tom", "John", NULL};
|
||||
10 }
|
||||
**(gdb) b 10**
|
||||
Breakpoint 1 at 0x8048418: file array.c, line 10.
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/array
|
||||
warning: Could not load shared library symbols for linux-gate.so.1.
|
||||
Do you need "set solib-search-path" or "set sysroot"?
|
||||
|
||||
Breakpoint 1, main () at array.c:10
|
||||
10 }
|
||||
**(gdb) disassemble main**
|
||||
Dump of assembler code for function main:
|
||||
0x080483cc <+0>: push %ebp
|
||||
0x080483cd <+1>: mov %esp,%ebp
|
||||
0x080483cf <+3>: sub $0x30,%esp
|
||||
0x080483d2 <+6>: movl $0x1,-0x10(%ebp)
|
||||
0x080483d9 <+13>: movl $0x2,-0xc(%ebp)
|
||||
0x080483e0 <+20>: movl $0x3,-0x8(%ebp)
|
||||
0x080483e7 <+27>: movl $0x80484b0,-0x1c(%ebp)
|
||||
0x080483ee <+34>: movl $0x80484b4,-0x18(%ebp)
|
||||
0x080483f5 <+41>: movl $0x0,-0x14(%ebp)
|
||||
0x080483fc <+48>: movl $0x80484b0,-0x28(%ebp)
|
||||
0x08048403 <+55>: movl $0x80484b4,-0x24(%ebp)
|
||||
0x0804840a <+62>: movl $0x0,-0x20(%ebp)
|
||||
0x08048411 <+69>: movl $0x80484b0,-0x4(%ebp)
|
||||
=> 0x08048418 <+76>: leave
|
||||
0x08048419 <+77>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) bt**
|
||||
#0 main () at array.c:10
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff980:
|
||||
eip = 0x8048418 in main (array.c:10); saved eip 0xb7e28605
|
||||
source language c.
|
||||
Arglist at 0xbffff978, args:
|
||||
Locals at 0xbffff978, Previous frame's sp is 0xbffff980
|
||||
Saved registers:
|
||||
ebp at 0xbffff978, eip at 0xbffff97c
|
||||
**(gdb) info locals**
|
||||
ia = {1, 2, 3}
|
||||
cpa = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
|
||||
cpa2 = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
|
||||
__cpa3 = 0x80484b0__
|
||||
//可见ia, cpa, cpa2为数组名称,而cpa3为一指针变量,其值为0x80484b0。
|
||||
BIN
Zim/Utils/gdb/gdb_debugging/stack.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
250
Zim/Utils/gdb/gdb_frame.txt
Normal file
@@ -0,0 +1,250 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T10:31:03+08:00
|
||||
|
||||
====== gdb frame ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
char **friends = {"Tom", "John", "Pi", \0};
|
||||
等价于 char *friends[ ] = {"Tom", "John", "Pi", \0};
|
||||
等价于 char *friends[4] = {"Tom", "John", "Pi", \0};
|
||||
|
||||
[geekard@geekard rel]$ gdb rel2
|
||||
GNU gdb (GDB) 7.5.1
|
||||
**(gdb) b greeting**
|
||||
Breakpoint 1 at 0x8048432: file rel2.c, line 8.
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/rel/rel2
|
||||
warning: Could not load shared library symbols for linux-gate.so.1.
|
||||
Do you need "set solib-search-path" or "set sysroot"?
|
||||
3
|
||||
Breakpoint 1, greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
8 printf("Hello, %s:\n", name);
|
||||
**(gdb) disassemble**
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x18,%esp
|
||||
上面这三条指令称为prologue,由gcc自动添加。break fuction会在执行完function的prologue后停止,这样
|
||||
=> 0x08048432 <+6>: mov 0x8(%ebp),%eax
|
||||
0x08048435 <+9>: mov %eax,0x4(%esp)
|
||||
0x08048439 <+13>: movl $0x8048590,(%esp)
|
||||
0x08048440 <+20>: call 0x80482f0 <printf@plt>
|
||||
**(gdb) si //多次执行si,直到输出如下字符串**
|
||||
0x080482f0 in printf@plt ()
|
||||
**(gdb) bt**
|
||||
#0 0x080482f0 in printf@plt ()
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
#2 0x080484fd in main () at [[rel2.c:28]]
|
||||
**(gdb) info frame 2**
|
||||
Stack frame at 0xbffff970:
|
||||
eip = 0x80484fd in main (rel2.c:28); saved eip 0xb7e28605
|
||||
caller of frame at 0xbffff930
|
||||
source language c.
|
||||
Arglist at 0xbffff968, args:
|
||||
Locals at 0xbffff968, Previous frame's sp is 0xbffff970
|
||||
Saved registers:
|
||||
ebp at 0xbffff968, eip at 0xbffff96c
|
||||
**(gdb) info frame 1**
|
||||
Stack frame at 0xbffff930:
|
||||
eip = 0x8048445 in greeting (rel2.c:8); saved eip 0x80484fd
|
||||
called by frame at 0xbffff970, caller of frame at 0xbffff910
|
||||
source language c.
|
||||
Arglist at 0xbffff928, args: name=0x80485c9 "geekard", age=23, friends=0xbffff944
|
||||
Locals at 0xbffff928, Previous frame's sp is 0xbffff930
|
||||
Saved registers:
|
||||
ebp at 0xbffff928, eip at 0xbffff92c
|
||||
**(gdb) info frame 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0x80482f0 in printf@plt; saved eip 0x8048445
|
||||
called by frame at 0xbffff930
|
||||
Arglist at 0xbffff908, args:
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers: //没有保存ebp, esi, edi, ebx寄存器的值。
|
||||
eip at 0xbffff90c
|
||||
|
||||
**(gdb) disassemble main**
|
||||
Dump of assembler code for function main:
|
||||
0x0804848a <+0>: push %ebp
|
||||
0x0804848b <+1>: mov %esp,%ebp
|
||||
0x0804848d <+3>: and $0xfffffff0,%esp
|
||||
0x08048490 <+6>: sub $0x30,%esp
|
||||
0x08048493 <+9>: mov 0x8049804,%eax
|
||||
0x08048498 <+14>: mov %eax,0x2c(%esp)
|
||||
0x0804849c <+18>: movl $0x80485c9,0x28(%esp)
|
||||
0x080484a4 <+26>: movl $0x17,0x24(%esp)
|
||||
0x080484ac <+34>: movl $0x80485d1,0x14(%esp)
|
||||
0x080484b4 <+42>: movl $0x80485d5,0x18(%esp)
|
||||
0x080484bc <+50>: movl $0x80485da,0x1c(%esp)
|
||||
0x080484c4 <+58>: movl $0x0,0x20(%esp)
|
||||
0x080484cc <+66>: mov 0x8049808,%eax
|
||||
0x080484d1 <+71>: mov %eax,0x4(%esp)
|
||||
0x080484d5 <+75>: movl $0x80485dd,(%esp)
|
||||
0x080484dc <+82>: call 0x80482f0 <printf@plt>
|
||||
0x080484e1 <+87>: lea 0x14(%esp),%eax
|
||||
0x080484e5 <+91>: mov %eax,0x8(%esp)
|
||||
0x080484e9 <+95>: mov 0x24(%esp),%eax
|
||||
0x080484ed <+99>: mov %eax,0x4(%esp)
|
||||
0x080484f1 <+103>: mov 0x28(%esp),%eax
|
||||
0x080484f5 <+107>: mov %eax,(%esp)
|
||||
0x080484f8 <+110>: call __0x804842c__ <greeting>
|
||||
__0x080484fd__ <+115>: leave
|
||||
0x080484fe <+116>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) disassemble greeting**
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x18,%esp
|
||||
0x08048432 <+6>: mov 0x8(%ebp),%eax
|
||||
0x08048435 <+9>: mov %eax,0x4(%esp)
|
||||
0x08048439 <+13>: movl $0x8048590,(%esp)
|
||||
0x08048440 <+20>: call __0x80482f0__ <printf@plt>
|
||||
__0x08048445__ <+25>: mov 0xc(%ebp),%eax
|
||||
0x08048448 <+28>: mov %eax,0x4(%esp)
|
||||
0x0804844c <+32>: movl $0x804859c,(%esp)
|
||||
0x08048453 <+39>: call 0x80482f0 <printf@plt>
|
||||
0x08048458 <+44>: movl $0x80485af,(%esp)
|
||||
0x0804845f <+51>: call 0x8048300 <puts@plt>
|
||||
0x08048464 <+56>: jmp 0x804847f <greeting+83>
|
||||
0x08048466 <+58>: mov 0x10(%ebp),%eax
|
||||
0x08048469 <+61>: mov (%eax),%eax
|
||||
0x0804846b <+63>: mov %eax,0x4(%esp)
|
||||
0x0804846f <+67>: movl $0x80485c3,(%esp)
|
||||
0x08048476 <+74>: call 0x80482f0 <printf@plt>
|
||||
0x0804847b <+79>: addl $0x4,0x10(%ebp)
|
||||
0x0804847f <+83>: mov 0x10(%ebp),%eax
|
||||
0x08048482 <+86>: mov (%eax),%eax
|
||||
0x08048484 <+88>: test %eax,%eax
|
||||
0x08048486 <+90>: jne 0x8048466 <greeting+58>
|
||||
0x08048488 <+92>: leave
|
||||
0x08048489 <+93>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) x /8wx 0x80482f0**
|
||||
0x80482f0 <printf@plt>: 0x97ec25ff 0x00680804 0xe9000000 0xffffffe0
|
||||
0x8048300 <puts@plt>: 0x97f025ff 0x08680804 0xe9000000 0xffffffd0
|
||||
**(gdb) x /8wi 0x80482f0**
|
||||
__0x80482f0__ <printf@plt>: jmp *__0x80497ec__
|
||||
0x80482f6 <printf@plt+6>: push $0x0
|
||||
0x80482fb <printf@plt+11>: jmp 0x80482e0
|
||||
0x8048300 <puts@plt>: jmp *0x80497f0
|
||||
0x8048306 <puts@plt+6>: push $0x8
|
||||
0x804830b <puts@plt+11>: jmp 0x80482e0
|
||||
0x8048310 <__gmon_start__@plt>: jmp *0x80497f4
|
||||
0x8048316 <__gmon_start__@plt+6>: push $0x10
|
||||
**(gdb) x /wx 0x80497ec**
|
||||
0x80497ec <printf@got.plt>: 0xb7e5bed0
|
||||
**(gdb) si**
|
||||
0xb7e5bed0 in printf () from [[/usr/lib/libc.so.6]]
|
||||
**(gdb) disassemble *0x80497ec**
|
||||
Dump of assembler code for function __printf__:
|
||||
=> __0xb7e5bed0__ <+0>: push %ebx
|
||||
0xb7e5bed1 <+1>: sub $0x18,%esp
|
||||
0xb7e5bed4 <+4>: call 0xb7f376d3 <__x86.get_pc_thunk.bx>
|
||||
0xb7e5bed9 <+9>: add $0x159127,%ebx
|
||||
0xb7e5bedf <+15>: lea 0x24(%esp),%eax
|
||||
0xb7e5bee3 <+19>: mov %eax,0x8(%esp)
|
||||
0xb7e5bee7 <+23>: mov 0x20(%esp),%eax
|
||||
0xb7e5beeb <+27>: mov %eax,0x4(%esp)
|
||||
0xb7e5beef <+31>: mov -0x68(%ebx),%eax
|
||||
0xb7e5bef5 <+37>: mov (%eax),%eax
|
||||
0xb7e5bef7 <+39>: mov %eax,(%esp)
|
||||
0xb7e5befa <+42>: call 0xb7e520f0 <vfprintf>
|
||||
0xb7e5beff <+47>: add $0x18,%esp
|
||||
0xb7e5bf02 <+50>: pop %ebx
|
||||
0xb7e5bf03 <+51>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) bt**
|
||||
#0 0xb7e5bed0 in printf () from /usr/lib/libc.so.6
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
#2 0x080484fd in main () at rel2.c:28
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0xb7e5bed0 in printf; saved eip 0x8048445
|
||||
called by frame at 0xbffff930
|
||||
Arglist at 0xbffff908, args:
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers:
|
||||
eip at 0xbffff90c
|
||||
没有保存ebp, esi, edi, ebx等寄存器的值,所以它们的值与frame 1中的相等。在编译时如果指定-fomit-frame-pointer选项,则
|
||||
编译器为函数调用生成栈帧时不会圧入ebp寄存器的值,而且对arguments和auto variables的引用是通过esp进行的。这样可以将
|
||||
ebp寄存器节省出来,用作其它用途。但缺点是无法对函数调用进行frame backtrace(如果目标文件中有.eh_frame section则gdb可以
|
||||
从中提取出frame backtrace信息)。
|
||||
|
||||
**(gdb) info registers**
|
||||
eax 0x80485c9 134514121
|
||||
ecx 0x0 0
|
||||
edx 0x0 0
|
||||
ebx 0xb7fb5000 -1208266752 //继续保存的是frame 1中的值
|
||||
esp 0xbffff90c 0xbffff90c
|
||||
ebp 0xbffff928 0xbffff928 //继续保存的是frame 1中的值
|
||||
esi 0x0 0
|
||||
edi 0x0 0
|
||||
eip 0xb7e5bed0 0xb7e5bed0 <printf>
|
||||
eflags 0x200282 [ SF IF ID ]
|
||||
cs 0x73 115
|
||||
ss 0x7b 123
|
||||
ds 0x7b 123
|
||||
es 0x7b 123
|
||||
fs 0x0 0
|
||||
gs 0x33 51
|
||||
**(gdb) f 1 //切换frame到#1, 这样可以查看greeting函数的参数和自动变量值。**
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
8 printf("Hello, %s:\n", name);
|
||||
**(gdb) info registers** //打印frame 1的寄存器
|
||||
eax 0x80485c9 134514121
|
||||
ecx 0x0 0
|
||||
edx 0x0 0
|
||||
ebx **0xb7fb5000** -1208266752
|
||||
esp 0xbffff910 0xbffff910
|
||||
ebp **0xbffff928** 0xbffff928
|
||||
esi 0x0 0
|
||||
edi 0x0 0
|
||||
eip 0x8048445 0x8048445 <greeting+25>
|
||||
eflags 0x200282 [ SF IF ID ]
|
||||
cs 0x73 115
|
||||
ss 0x7b 123
|
||||
ds 0x7b 123
|
||||
es 0x7b 123
|
||||
fs 0x0 0
|
||||
gs 0x33 51
|
||||
(gdb)
|
||||
|
||||
|
||||
(gdb)
|
||||
**(gdb) info args**
|
||||
name = 0x80485c9 "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff944
|
||||
**(gdb) ptype friends**
|
||||
type = char **
|
||||
|
||||
**(gdb) p friends**
|
||||
$1 = (char **) 0xbffff944
|
||||
**(gdb) p *friends**
|
||||
$6 = 0x80485d1 "Tom"
|
||||
**(gdb) p friends+1**
|
||||
$2 = (char **) 0xbffff948
|
||||
**(gdb) x /4wx friends**
|
||||
0xbffff944: 0x080485d1 0x080485d5 0x080485da 0x00000000
|
||||
**(gdb) p *friends@4**
|
||||
$4 = {0x80485d1 "Tom", 0x80485d5 "John", 0x80485da "Pi", 0x0}
|
||||
|
||||
**(gdb) p &friends**
|
||||
$5 = (char ***) 0xbffff938
|
||||
|
||||
(**gdb) x /4wx friends+1**
|
||||
0xbffff948: 0x080485d5 0x080485da 0x00000000 0x00000017
|
||||
**(gdb) x /4wx &friends**
|
||||
0xbffff938: 0xbffff944 0x08048552 0x00000001 0x080485d1
|
||||
**(gdb) p friends@4**
|
||||
$3 = {0xbffff944, 0x8048552 <__libc_csu_init+82>, 0x1, 0x80485d1}
|
||||
|
||||
**(gdb) x /wx friends**
|
||||
0xbffff944: 0x080485d1
|
||||
**(gdb) x /wx friends+1**
|
||||
0xbffff948: 0x080485d5
|
||||
**(gdb) x /wx &friends**
|
||||
0xbffff938: 0xbffff944
|
||||
**(gdb) x /wx *friends**
|
||||
0x80485d1: 0x006d6f54
|
||||
@@ -49,7 +49,7 @@ TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can | __bridge__ }
|
||||
link/ether c8:60:00:8a:db:e7 brd ff:ff:ff:ff:ff:ff
|
||||
|
||||
[geekard@kb310 man]$ __sudo ip link add link eth0 name demo-bridge type bridge; ip link show__
|
||||
**#命令行中的link eth0其实不用加。**
|
||||
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT
|
||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 576 qdisc pfifo_fast state __UP__ mode DEFAULT qlen 1000
|
||||
@@ -148,6 +148,11 @@ rtt min/avg/max/mdev = 0.385/0.546/0.959/0.239 ms
|
||||
Password:
|
||||
RTNETLINK answers: No such file or directory
|
||||
[geekard@kb310 ~]$ __sudo ip route add default via 192.168.1.1 dev demo-bridge__
|
||||
注意,添加路由的格式为:ip route add PREFIX via ADDRESS dev DEV
|
||||
其中PREFIX表示目标网络,如果为缺省路由则因为default。
|
||||
via ADDRESS是可选的,表示到到PREFIX目标网络需要经过ADDRESS表示的路由器,__ADDRESS不用前缀形式__。
|
||||
[geekard@geekard rel]$ sudo ip route add default via 192.168.1.1/24 dev demo
|
||||
Error: an inet address is expected rather than "192.168.1.1/24".
|
||||
[geekard@kb310 ~]$ __ip route show table all__
|
||||
**default via 192.168.1.1 dev demo-bridge **
|
||||
**default via 192.168.1.1 dev eth0 metric 202**
|
||||
|
||||
2628
Zim/Utils/systemd.txt
Normal file
@@ -0,0 +1,167 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-20T20:10:35+08:00
|
||||
|
||||
====== Booting up-Tools and tips for systemd a Linux init tool ======
|
||||
Created Tuesday 20 November 2012
|
||||
http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html
|
||||
|
||||
15 May 2012, 10:00
|
||||
|
||||
Booting up: Tools and tips for systemd, a Linux init tool
|
||||
by Lennart Poettering, Kay Sievers, Thorsten Leemhuis
|
||||
|
||||
These days, Fedora, openSUSE, Mandriva and a few other distributions use the **systemd init tool** for system starts. It includes its own tools for configuration and diagnosis, and the tricks it needs when the system doesn't start are different from sysvinit's.
|
||||
|
||||
The following article about systemd was first published in the German magazine c't 13/11 and has been updated in various places before appearing in The H Open. An article from the same issue of c't on systemd's ideas, approach and functionality was also recently published on The H Open.
|
||||
|
||||
The systemd init tool, just over two years old, is already the default in some distributions; a few more include it as an alternative to **upstart** and the outdated **sysvinit**. Thanks to __compatibility features__, some of the commands and tricks familiar from distributions with sysvinit and upstart work with systemd too. To really take advantage of the much newer init system's capabilities, however, administrators should get to know systemd's tools and parameters as well.
|
||||
|
||||
The main tool for interacting with systemd is **systemctl**, a command-line program. The tool requires root privileges to make changes to the configuration or to restart background services, but even non-root users can use some diagnostic requests. If you launch the program without any parameters, you will see a list of the "units" that execute tasks when the system is started, including mounting and checking disks, starting background services and configuring hardware.
|
||||
|
||||
For a standard Fedora 15 installation, systemctl lists around 160 active units, divided into ten types. __Service units__ are one of the most important types of units as they take care of background services, which a sysvinit distribution typically starts using init scripts. __Mount and automount units__ mount filesystems. __Socket units__ create sockets and, as soon as a socket is accessed, indirectly start another unit using dependencies. You can use a parameter to tell systemctl to only list certain types of unit, for example all service units:
|
||||
|
||||
**systemctl --type=service**
|
||||
|
||||
Systemctl automatically forwards its task to less; you can use the arrow keys to scroll not just up and down but also to the right, since more information is occasionally "hidden" there.
|
||||
|
||||
To boot a system, systemd uses units, which are divided into types that systemctl can list separately. The first column in the list tells you the name of the unit; the second column, whether systemd was able to **load the unit definition**. The third column says whether the unit is active. If you include the -a parameter, the program only displays **inactive units** – that is, units that are installed but not used during boot-up; the same applies to unit files that the init system wasn't able to load, most likely because of an error in the unit file.
|
||||
|
||||
The fourth column gives the current status: "exited" means that the process **completed without any errors**. This is the case for, say, services that don't continue in the background after they've been launched – for example, the service unit that, for compatibility reasons, executes the /etc/rc.d/rc.local file, familiar from sysvinit, at system start. "Running" is for services that are running in the background, such as cron, dbus, sshd and udev.
|
||||
|
||||
The sixth column describes the unit. Units labelled "LSB" or "SYSV" have been automatically created by systemd to take care of traditional init scripts.
|
||||
|
||||
Services that could not be started or that crashed later are marked as "failed" in the fifth column, in red, if the console can display colours. You can find out when the crash happened and which error code the program provided when it ended using commands such as:
|
||||
|
||||
systemctl status ntpd.service
|
||||
|
||||
Systemctl's status command provides a time and error code for crashed services Zoom For a newly installed Fedora 15, systemctl lists about 60 service units, including the login processes for the text consoles (agetty), since – unlike sysvinit – systemd uses service units to manage these like a normal background service.
|
||||
|
||||
Next: Unit files and targets
|
||||
|
||||
===== Working with units =====
|
||||
|
||||
The system configuration files for creating units are in **/lib/systemd/system/**, but a file with the same name in **/etc/systemd/system** will take priority.
|
||||
|
||||
Unit definitions are usually much shorter than the classic sysvinit scripts. For example, a unit file for the service for synchronising network time via NTP is just a few lines long:
|
||||
|
||||
[Unit]
|
||||
Description=Network Time Service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/ntpd -n -u ntp:ntp -g
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
All unit files include a section, starting with __[Unit]__, with general settings and a short description. The __[Service]__ section has service-specific tasks – for NTP, just the command-line to launch the service. If a specific command is required to end the program, you can set it using **ExecStop=**. This step is unnecessary for the NTP daemon, since, following Unix tradition, it can be ended with a simple "SIGTERM" signal, which tells systemd to end if no other command has been specified.
|
||||
|
||||
The **[Install]** section contains instructions for systemd to interpret during (de-)installation; the entry in the NTP example means that the time should be synchronised when the "Multi-User" target is activated.
|
||||
|
||||
===== Targets =====
|
||||
**The concept of "targets" units is similar to that of sysvinit's runlevels;** indeed, for compatibility, systemd even understands runlevel names for equivalent targets. In Fedora 15, you can therefore enter the familiar single as a parameter in the kernel's boot-loader; systemd then activates **rescue.target**, which provides a minimal interface comparable to single-user mode.
|
||||
|
||||
Along the same lines, 3 can be used to activate a multi-user mode – that is, to fully start the system without using the graphical login interface. In systemd, this mode is represented by the **multi-user.target uni**t, which can be set as the standard with this link:
|
||||
|
||||
ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
|
||||
|
||||
If, at a later point, you do want the graphical login interface to be a standard part of boot-up, you can set **graphical.target** as the standard target in the same way; this is the equivalent of runlevel 5 in older versions of Fedora and openSUSE. As an alternative to the old runlevels, you can also give the kernel the names of the target units to be started:
|
||||
|
||||
__systemd.unit=multi-user.target__
|
||||
|
||||
**To activate a different target unit during operation**, you can use systemctl's isolate command, which requires root privileges:
|
||||
|
||||
systemctl isolate rescue.target
|
||||
|
||||
The change to the rescue target is interesting for administration tasks, since systemd now ends all user logins and background services so that only system services run, such as the one monitoring logical volumes (lvm2-monitor). Sometimes, even these services need to be ended for rebuilds; you can then use **emergency.target** to go to emergency mode, where only the process for the input prompt runs, along with the kernel threads.
|
||||
|
||||
===== Wants and needs =====
|
||||
Systemctl's show command delivers some internal information on running units and the tasks they execute, as well as information about which units systemd calls on to enable the multi-user target:
|
||||
|
||||
**systemctl show -p Wants multi-user.target**
|
||||
|
||||
Other targets can also be in the output, such as **basic.target** in multi-user.target. In turn, the former depends on **sysinit.target**, which requires **local-fs.target**. These three targets take care of the system's basic configuration, including mounting filesystems and starting udev. To specify dependency on the basic target, the unit configuration file multi-user.target contains the following statements:
|
||||
|
||||
Requires=basic.target
|
||||
After=basic.target
|
||||
|
||||
With After in addition to Requires, systemd knows that it must __not only enable the target but also wait for that target__ to completely start.
|
||||
|
||||
__Wants is a weaker alternative to Requires__. Systemd enables these units as well, but continues starting the system even if one of them doesn't start. This kind of dependency can also be specified with links to unit files in directories consisting of the unit file's path and name and a .wants in order to determine which units are retrieved when a target is accessed.__(也就是说,这种依赖关系可以通过在unit name +.wants目录中建立被依赖unit的link方式创建。)__ You can use ls or systemctl's show command:
|
||||
|
||||
ls /*/systemd/system/multi-user.target.wants/
|
||||
systemctl show -p Wants multi-user.target
|
||||
|
||||
===== Shutting down =====
|
||||
|
||||
If you want to deactivate the NTPD service unit so the system time is not synchronised via NTP upon boot-up, you can use the following style of command:
|
||||
|
||||
systemctl disable ntpd.service
|
||||
|
||||
Here, systemctl is simply removing the link to the service unit file **in the Wants directories**; it creates a link when a service is activated with **enable**. Both steps can also be done manually in order to (de)activate units without using systemctl.
|
||||
|
||||
__也就是说,systemctl disable ntpd.service会将该unit file 的链接从/etc/systemd/system/multi-user.targets.wants目录中删除。__
|
||||
__systemctl enable ntpd.service会将该unit file的链接建立在上面的目录中。__
|
||||
|
||||
If a service is started by a traditional init script rather than a unit, __systemctl forwards the activation request to the chkconfig program__. With Fedora 15, for example, this can occur when you install Apache and activate it using systemctl. In turn, chkconfig can also delegate tasks to systemctl in Fedora 15 – but only some, so you're better off not using it at all or only with caution.
|
||||
|
||||
The (de)activation of a service takes effect the next time it is started or when the system is shut down; the following command starts a service immediately:
|
||||
|
||||
systemctl start ntpd.service
|
||||
|
||||
For sysvinit distributions, the equivalent to this command is **service ntpd start**. A systemctl command with the **stop** parameter instead of start ends the service. With the **status** command, systemctl delivers information about the unit, including its current status and the name of the file that specifies it. The program also says whether the service is currently running and, if so, for how long it has been running as well as which processes belong to it, with the main process explicitly displayed.
|
||||
|
||||
Group affiliation can be used to determine which service a process belongs to. It is quite easy to find out which service started which processes by looking at the control groups created by systemd. The command __systemd-cgls__ displays the cgroup hierarchy created by systemd; alternatively, ps shows group affiliation:
|
||||
|
||||
ps xaw -eo pid,args,cgroup
|
||||
|
||||
Next: Fixing problems
|
||||
|
||||
===== Stopped at the starting line =====
|
||||
|
||||
If there are problems during boot-up that systemd seems to be directly or indirectly involved in, start the kernel with the following parameters:
|
||||
|
||||
**systemd.log_target=kmsg systemd.log_level=debug**
|
||||
|
||||
Systemd recognises the parameters and provides extensive troubleshooting information on the console. At the same time, the information is saved for later analysis in the kernel notification buffer created by dmesg.
|
||||
|
||||
The "systemd-cgls" tool can display the control groups and the processes belonging to them.
|
||||
|
||||
The command line programs __poweroff, halt and reboot are part of systemd,__ but the system can also be shut down or restarted using systemctl commands, which are the same. The system can also be restarted this way:
|
||||
|
||||
systemctl kexec
|
||||
|
||||
After all services have been stopped, systemd tells the running kernel to directly start a previously configured Linux kernel, which allows for fast restarts, since it bypasses BIOS and boot-loader. If no kexec kernel is configured, systemd executes a normal restart.
|
||||
|
||||
===== Deep down =====
|
||||
For standard administration tasks, you will usually only come into contact with **service and target units**; the others are primarily important for deeper systemd functions or, during boot-up, take care of everything that __distribution-specific scripts__ took care of in sysvinit and upstart distributions. These tasks include mounting the filesystems specified in /etc/fstab, activating the swap space and occasionally cleaning up directories for temporary files.
|
||||
|
||||
For some of these tasks, systemd has an **automount** function that can create pseudo mount points for filesystems configured in /etc/fstab; they are not really mounted until they are first accessed. Adding **comment=systemd.automount** in /etc/fstab changes any mount point into an automount point, which can speed up the boot-up process and be interesting for access to network shares, since the WLAN connection is not created until the user uses NetworkManager.
|
||||
|
||||
===== Looking for answers =====
|
||||
Systemctl can be used to tell systemd to **send a signal without knowing the service's process ID**. For example, the following command puts rsyslogd in debug mode, which is ended when you enter the command a second time.
|
||||
|
||||
**systemctl kill** --signal=USR1 rsyslogd.service
|
||||
|
||||
If you don't specify which signal to send, systemctl sends a normal term signal, which ends all processes belonging to a service.
|
||||
|
||||
Systemd includes a program that __visualises the boot processes__; the dark red areas signal services' start phases .The command systemd-analyze tells you how long the system took to boot and how much of that time was due to the kernel, initramfs and the systemd-controlled configuring of the userland. If you want to look more closely into the latter factor, use **systemd-analyze blame** to get individual units' start times. For more detailed information on the boot process, the program can create an SVG file that visualises the units' starts:
|
||||
|
||||
__systemd-analyze plot > plot.svg__
|
||||
|
||||
Sometimes, this can be used to track down units that excessively prolong boot-up. The seventh part of the "Systemd for Administrators" blog series has a few tips on correctly interpreting these results. The series, with twelve sections at the moment, also includes many other tips and notes on using systemd:
|
||||
|
||||
* Verifying Bootup
|
||||
* Which Service Owns Which Processes?
|
||||
* How Do I Convert A SysV Init Script Into A systemd Service File?
|
||||
* Killing Services
|
||||
* The Three Levels of "Off"
|
||||
* Changing Roots
|
||||
* The Blame Game
|
||||
* The New Configuration Files
|
||||
* On /etc/sysconfig and /etc/default
|
||||
* Instantiated Services
|
||||
* Converting inetd Services
|
||||
* Securing Your Services
|
||||
|
||||
Lennart Poettering's homepage also has many other articles with more background information on the init system. In addition, Poettering recently listed some of the changes made to systemd in the last year and a half in his third "Systemd Status Update".
|
||||
273
Zim/Utils/systemd/systemd_for_Administrators,_Part_1.txt
Normal file
@@ -0,0 +1,273 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-21T19:33:39+08:00
|
||||
|
||||
====== systemd for Administrators, Part 1 ======
|
||||
Created Wednesday 21 November 2012
|
||||
http://www.0pointer.de/blog/projects/systemd-for-admins-1.html
|
||||
|
||||
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
|
||||
|
||||
Mon, 23 Aug 2010
|
||||
systemd for Administrators, Part 1
|
||||
|
||||
As many of you know, systemd is the new Fedora init system, starting with F14, and it is also on its way to being adopted in a number of other distributions as well (for example, OpenSUSE). For administrators systemd provides a variety of new features and changes and enhances the administrative process substantially. This blog story is the first part of a series of articles I plan to post roughly every week for the next months. In every post I will try to explain one new feature of systemd. Many of these features are small and simple, so these stories should be interesting to a broader audience. However, from time to time we'll dive a little bit deeper into the great new features systemd provides you with.
|
||||
|
||||
===== Verifying Bootup =====
|
||||
Traditionally, when booting up a Linux system, you see a lot of little messages passing by on your screen. As we work on speeding up and parallelizing the boot process these messages are becoming visible for a shorter and shorter time only and be less and less readable -- if they are shown at all, given we use __graphical boot splash__ technology like **Plymouth** these days. Nonetheless the information of the boot screens was and still is very relevant, because it shows you for each service that is being started as part of bootup, wether it managed to start up successfully or failed (with those green or red [ OK ] or [ FAILED ] indicators). To improve the situation for machines that boot up fast and parallelized and to make this information more nicely available during runtime, we added a feature to systemd that tracks and remembers for each service whether it started up successfully, whether it exited with a non-zero exit code, whether it timed out, or whether it terminated abnormally (by segfaulting or similar), both during start-up and runtime. By simply typing systemctl in your shell you can query the state of all services, both **systemd native and SysV/LSB services**:
|
||||
|
||||
[root@lambda] ~# systemctl
|
||||
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
|
||||
dev-hugepages.automount loaded active running Huge Pages File System Automount Point
|
||||
dev-mqueue.automount loaded active running POSIX Message Queue File System Automount Point
|
||||
proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point
|
||||
sys-kernel-debug.automount loaded active waiting Debug File System Automount Point
|
||||
sys-kernel-security.automount loaded active waiting Security File System Automount Point
|
||||
sys-devices-pc...0000:02:00.0-net-eth0.device loaded active plugged 82573L Gigabit Ethernet Controller
|
||||
[...]
|
||||
sys-devices-virtual-tty-tty9.device loaded active plugged /sys/devices/virtual/tty/tty9
|
||||
-.mount loaded active mounted /
|
||||
boot.mount loaded active mounted /boot
|
||||
dev-hugepages.mount loaded active mounted Huge Pages File System
|
||||
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
|
||||
home.mount loaded active mounted /home
|
||||
proc-sys-fs-binfmt_misc.mount loaded active mounted Arbitrary Executable File Formats File System
|
||||
abrtd.service loaded active running ABRT Automated Bug Reporting Tool
|
||||
accounts-daemon.service loaded active running Accounts Service
|
||||
acpid.service loaded active running ACPI Event Daemon
|
||||
atd.service loaded active running Execution Queue Daemon
|
||||
auditd.service loaded active running Security Auditing Service
|
||||
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
|
||||
bluetooth.service loaded active running Bluetooth Manager
|
||||
console-kit-daemon.service loaded active running Console Manager
|
||||
cpuspeed.service loaded active exited LSB: processor frequency scaling support
|
||||
crond.service loaded active running Command Scheduler
|
||||
cups.service loaded active running CUPS Printing Service
|
||||
dbus.service loaded active running D-Bus System Message Bus
|
||||
getty@tty2.service loaded active running Getty on tty2
|
||||
getty@tty3.service loaded active running Getty on tty3
|
||||
getty@tty4.service loaded active running Getty on tty4
|
||||
getty@tty5.service loaded active running Getty on tty5
|
||||
getty@tty6.service loaded active running Getty on tty6
|
||||
haldaemon.service loaded active running Hardware Manager
|
||||
hdapsd@sda.service loaded active running sda shock protection daemon
|
||||
irqbalance.service loaded active running LSB: start and stop irqbalance daemon
|
||||
iscsi.service loaded active exited LSB: Starts and stops login and scanning of iSCSI devices.
|
||||
iscsid.service loaded active exited LSB: Starts and stops login iSCSI daemon.
|
||||
livesys-late.service loaded active exited LSB: Late init script for live image.
|
||||
livesys.service loaded active exited LSB: Init script for live image.
|
||||
lvm2-monitor.service loaded active exited LSB: Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
|
||||
mdmonitor.service loaded active running LSB: Start and stop the MD software RAID monitor
|
||||
modem-manager.service loaded active running Modem Manager
|
||||
netfs.service loaded active exited LSB: Mount and unmount network filesystems.
|
||||
NetworkManager.service loaded active running Network Manager
|
||||
ntpd.service loaded maintenance maintenance Network Time Service
|
||||
polkitd.service loaded active running Policy Manager
|
||||
prefdm.service loaded active running Display Manager
|
||||
rc-local.service loaded active exited /etc/rc.local Compatibility
|
||||
rpcbind.service loaded active running RPC Portmapper Service
|
||||
rsyslog.service loaded active running System Logging Service
|
||||
rtkit-daemon.service loaded active running RealtimeKit Scheduling Policy Service
|
||||
sendmail.service loaded active running LSB: start and stop sendmail
|
||||
sshd@172.31.0.53:22-172.31.0.4:36368.service loaded active running SSH Per-Connection Server
|
||||
sysinit.service loaded active running System Initialization
|
||||
systemd-logger.service loaded active running systemd Logging Daemon
|
||||
udev-post.service loaded active exited LSB: Moves the generated persistent udev rules to /etc/udev/rules.d
|
||||
udisks.service loaded active running Disk Manager
|
||||
upowerd.service loaded active running Power Manager
|
||||
wpa_supplicant.service loaded active running Wi-Fi Security Service
|
||||
avahi-daemon.socket loaded active listening Avahi mDNS/DNS-SD Stack Activation Socket
|
||||
cups.socket loaded active listening CUPS Printing Service Sockets
|
||||
dbus.socket loaded active running dbus.socket
|
||||
rpcbind.socket loaded active listening RPC Portmapper Socket
|
||||
sshd.socket loaded active listening sshd.socket
|
||||
systemd-initctl.socket loaded active listening systemd /dev/initctl Compatibility Socket
|
||||
systemd-logger.socket loaded active running systemd Logging Socket
|
||||
systemd-shutdownd.socket loaded active listening systemd Delayed Shutdown Socket
|
||||
dev-disk-by\x1...x1db22a\x1d870f1adf2732.swap loaded active active /dev/disk/by-uuid/fd626ef7-34a4-4958-b22a-870f1adf2732
|
||||
basic.target loaded active active Basic System
|
||||
bluetooth.target loaded active active Bluetooth
|
||||
dbus.target loaded active active D-Bus
|
||||
getty.target loaded active active Login Prompts
|
||||
graphical.target loaded active active Graphical Interface
|
||||
local-fs.target loaded active active Local File Systems
|
||||
multi-user.target loaded active active Multi-User
|
||||
network.target loaded active active Network
|
||||
remote-fs.target loaded active active Remote File Systems
|
||||
sockets.target loaded active active Sockets
|
||||
swap.target loaded active active Swap
|
||||
sysinit.target loaded active active System Initialization
|
||||
|
||||
LOAD = Reflects whether the unit definition was properly loaded.
|
||||
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
|
||||
SUB = The low-level unit activation state, values depend on unit type.
|
||||
JOB = Pending job for the unit.
|
||||
|
||||
221 units listed. Pass --all to see inactive units, too.
|
||||
[root@lambda] ~#
|
||||
|
||||
(I have shortened the output above a little, and removed a few lines not relevant for this blog post.)
|
||||
|
||||
Look at the **ACTIVE** column, which shows you the high-level state of a service (or in fact of any kind of unit systemd maintains, which can be more than just services, but we'll have a look on this in a later blog posting), whether it is active (i.e. running), inactive (i.e. not running) or in any other state. If you look closely you'll see one item in the list that is marked maintenance and highlighted in red. This informs you about a service that failed to run or otherwise encountered a problem. In this case this is ntpd. Now, let's find out what actually happened to ntpd, with the systemctl status command:
|
||||
|
||||
[root@lambda] ~# **systemctl status ntpd**__.service__
|
||||
ntpd.service - Network Time Service
|
||||
Loaded: loaded (/etc/systemd/system/ntpd.service)
|
||||
**Active: maintenance**
|
||||
Main: 953 (code=exited, status=255)
|
||||
CGroup: name=systemd:/systemd-1/ntpd.service
|
||||
[root@lambda] ~#
|
||||
|
||||
This shows us that NTP terminated during runtime (when it ran as **PID 953**), and tells us exactly the error condition: the process exited with an exit status of 255.
|
||||
|
||||
In a later systemd version, we plan to hook this up to ABRT, as soon as this enhancement request is fixed. Then, if systemctl status shows you information about a service that crashed it will direct you right-away to the appropriate crash dump in ABRT.
|
||||
|
||||
Summary: use systemctl and systemctl status as modern, more complete replacements for the traditional boot-up status messages of SysV services. systemctl status not only captures in more detail the error condition but also shows runtime errors in addition to start-up errors.
|
||||
|
||||
That's it for this week, make sure to come back next week, for the next posting about systemd for administrators!
|
||||
|
||||
posted at: 10:22 | path: /projects | permanent link to this entry | 40 comments
|
||||
Posted by bochecha at Mon Aug 23 11:20:20 2010
|
||||
Thanks, this serie of article will no doubt be very interesting. :)
|
||||
|
||||
About this one, I don't really get the **LOAD, ACTIVE and SUB** columns.
|
||||
|
||||
As I understood it, the first one indicates whether a unit **configuration** was loaded or not into systemd. But if it wasn't loaded, then it would not appear in the output of systemctl, right?
|
||||
|
||||
You say that ACTIVE is a high-level generalization of SUB. In this case, why is that necessary? Isn't SUB already enough information?
|
||||
|
||||
Maybe if you could give the list of the possible values for each columns then that would help me understand the differences. :)
|
||||
|
||||
Or maybe just point to the appropriate documentation if that is all already documented somewhere, I must admit I haven't had the time yet to look at Systemd as closely as I wanted.
|
||||
|
||||
Posted by Lennart at Mon Aug 23 11:35:34 2010
|
||||
bochecha: well, there are many reasons why a service might **show up as failed** to load in the systemctl output: for example, it was referenced as required dependency of another service, but we couldn't find neither a native service definition file nor a SysV init script for it. Or, there was a parsing failure while reading it. Or, because the file was incomplete. And that might even happen while a service is active, for example, because the user requested **a configuration file reload** from systemd after changing a service file, and a service that is already running suddenly has an invalid configuration file. That effectively means that the LOAD and the ACTIVE state are mostly orthogonal(正交、互相垂直): you may have a running service where configuration loaded fine, you may have a stopped service where it loaded fine, but you may also have a running service where configuration failed to load.
|
||||
|
||||
**LOAD和ACTIVE具有不同的功能,LOAD表明该service的configure file是否正常读取,而ACTIVE表明该serive是否在运行。一般来说LOAD失败时service也是failed,但是有可能正常运行的service在reload configration file时出错。**
|
||||
|
||||
And yes, ACTIVE and SUB show you the same information, though ACTIVE in a more generalized form. While SUB has states that are __specific to each unit type__ (e.g. **"running", "exited", "dead" for services; "plugged" and "dead" for devices; or "mounted" and "dead" for mount points**), ACTIVE exposes the same high-level states for all units.
|
||||
|
||||
ACTIVE较SUB表示的是一个更一般、抽象的状态,而SUB与具体的unit类型相关,表达的是更具体的信息。例如ACTIVE的状态是active但是SUB的内容可能是running或plugged或exited。
|
||||
|
||||
We only distuingish __6 ACTIVE states__ (to list them: **active, reloading, inactive, maintenance, activating, deactivating**), which are mapped from the lower-level states, which might be many more. For example __services have 15 low-level states__: **dead, start-pre, start, start-post, running, exited, reload, stop, stop-sigterm, stop-sigkill, stop-post, final-sigterm, final-sigkill, maintenance, auto-restart.**
|
||||
|
||||
Posted by John Drinkwater at Mon Aug 23 12:23:36 2010
|
||||
Why systemctl status ntpd.service and not systemctl status ntpd?
|
||||
Why does systemctl display names like getty@tty2.service and not as getty@tty2 ?
|
||||
|
||||
Do we really need to have .mount, .service, etc on all our config files now?
|
||||
IMO, horrible to have file extensions, equally to have them as long as the file name.
|
||||
|
||||
Posted by Lennart at Mon Aug 23 13:36:52 2010
|
||||
John, we support **different kinds of units**. We manage __sockets, mount points, services, devices, automount points, timers, paths, targets, swap files/devices and snapshots__ with the same tools, with the same commands. For example "dbus.service" and "dbus.socket" are both used by the D-Bus system, but can be controlled and introspected __independently__. To distuingish them, we hence write their full name everywhere, so that you explicitly state that you mean the D-Bus socket instead of the D-Bus service, or vice versa.
|
||||
|
||||
Also, I actually find this one of the pretty things in this design: the unit names are actually __identical__ to the file names they are configured in.
|
||||
|
||||
Posted by Shane Falco at Mon Aug 23 14:19:27 2010
|
||||
I'm with Mr. Drinkwater on this. Extensions (especially long extensions) are one symptom of a bad design. All this feels very rushed and hacked together.
|
||||
|
||||
It looks like this core systemctl function won't display cleanly in a standard 80 character wide terminal? Are we trying to change linux so much that we no longer care about those sorts of things? It may be different for gnome developers, but unix admins I know have lots of windows open and usually they're 80 characters wide.
|
||||
|
||||
Finally, why choose a name so close to another common utility? systemctl? Seriously? When another core system utility called sysctl already exists?
|
||||
|
||||
Posted by Lennart at Mon Aug 23 14:26:44 2010
|
||||
Shane, I am sorry but I guess we just have to agree to disagree to this. The points you raise are in the category "matter of taste" or even "bike shedding", and so I guess we should leave it as that.
|
||||
|
||||
systemctl shortens the output dependening the terminal size. If you use a tiny terminal, the description string might even be suppressed entirely. The bigger your terminal/screen is, the more output we can stick on it. That should not surprise anybody. Or to put it in other words: we support 80ch terminals just fine, but if you use bigger termiansl we'll make use of it.
|
||||
|
||||
Posted by Shane Falco at Mon Aug 23 14:49:26 2010
|
||||
Sounds reasonable and I appreciate the response. It looks like you are taking your own personal experience (which is all anyone can ask) and creating something that you think is appropriate. But I fear that you don't really see the bigger picture of unix admins out there...there are a lot of guys I work with who are junior/middle guys who just work for a paycheck. They're __not linux geeks__. I dare say they're the majority. They could be doing AIX or Solaris or linux for all they care. I think they're going to have trouble with systemd. It just does too much and it's too baroque. Too confusing.
|
||||
|
||||
I finally, finally got them going with services/chkconfig and now this...
|
||||
|
||||
Posted by Michael at Mon Aug 23 15:00:08 2010
|
||||
Just a quick question, can the description be translated ?
|
||||
I assume that this is not planned, as they are config file, not software, but as we are able to translate .desktop, it would be great to have some way of doing it cleanly.
|
||||
|
||||
Posted by Lennart at Mon Aug 23 15:10:54 2010
|
||||
Shane, well, what makes you think that we haven't looked around ourselves? Also, we managed to get systemd accepted by Fedora, in particular FESCO. We managed to convince this technical committee that systemd is a good thing. Do you really want to say that Fedora as a whole is incapable of "seeing the big picture", but you are the only one who is? Maybe things are the other way round? Ever thought about that?
|
||||
|
||||
Also, note that systemd actually brings Linux administration much closer to how many of these things are done on Solaris. Much of what we added is inspired by SMF, and other init systems. That means the administrators should enjoy how we make things on Linux work much more like the other big server operating systems.
|
||||
|
||||
Posted by Lennart at Mon Aug 23 15:13:46 2010
|
||||
Michael: it currently isn't translated, but the plan is to copy very closely the mechanism how .desktop files are translated (our unit definition files also use an .ini inspired format), so that we can reuse existing tools for this. This hasn't been implemented yet however.
|
||||
|
||||
Posted by Simon at Mon Aug 23 16:07:24 2010
|
||||
Shane Falco, you are being dishonest.
|
||||
|
||||
Your concern is that this change would require you to learn new things and have to teach new things.
|
||||
|
||||
The way you should rephrase your questions is:
|
||||
|
||||
“Sorry for being off-topic; I am posting this on the For Admins post while my concern is really about "Does systemd offer so many nice things that justifies the change?". I would like to see the question answered: "What are the advantages of systemd that justify this big change? I did not search your previous posts on this subjest."”
|
||||
|
||||
Posted by Diego at Mon Aug 23 16:21:50 2010
|
||||
What about gettext support?
|
||||
|
||||
Posted by Lennart at Mon Aug 23 16:42:09 2010
|
||||
Diego: it's unlikely we'll use the gettext APIs inside of PID 1, simply because i18n data tends to be stored in /usr, and we try to avoid accesses to that, since some folks still have that one a seperate partition (even though it is crazy and misses the point). However, for the client tools this is differentely and w'll certainly reuse the framworks currently used by other projects, be it gettext or intltool, or the hacks to make .desktop files translatable.
|
||||
ure people would hate me if i'd start moving i18n data to /lib...
|
||||
|
||||
Posted by Nagilum at Mon Aug 23 20:45:09 2010
|
||||
If ntpd.service would have emitted some error message while starting up, how would I display that using systemd?
|
||||
|
||||
Posted by Lennart at Mon Aug 23 20:49:05 2010
|
||||
Nagilum: by checking the logs. The long term plan is to hook up "systemctl status" to the logs, so that you'll see the most recent log messages generated by a service next to the service. But until that happened we need to beef up syslog considerable, i.e. make it indexable and stuff like that.
|
||||
|
||||
Posted by Denice at Tue Aug 24 00:43:45 2010
|
||||
I'm a little worried that anyone thinks Solaris' SMF is something worthy of copying. I find it horribly over-engineered. These days it is common to run virtual servers which do really only one thing (web server, or a mysql slave, or an ldap server). I have a number of xen guests that list perhaps 15 'chkconfig-ed on' services:
|
||||
chkconfig --list|grep :on
|
||||
|
||||
So from a system administrator's point of view, speaking of managing targeted servers and not multimedia desktops, I don't need anything complicated to manage runtime services.
|
||||
|
||||
You might want to seriously think about writing a tutorial for a typical small server (apache only, for example - no graphics, no bluetooth, no atd, no iscsi, etc.), and then convince us that systemd provides any value.
|
||||
|
||||
cheers, etc.
|
||||
|
||||
Posted by Shane at Tue Aug 24 01:49:13 2010
|
||||
Denice said it better than I ever could. As someone stuck with over a hundred Solaris 10 servers, I agree completely with her assessment.
|
||||
|
||||
Here's a nice little commentary on Apple's launchd which I feel is just as appropriate for systemd:
|
||||
|
||||
http://lowendmac.com/ed/winston/10kw/launchd.html
|
||||
|
||||
It's monolithic, it's "over engineered", and it does too many things. In a nutshell, it's anti-unix.
|
||||
|
||||
Posted by Karellen at Tue Aug 24 14:02:45 2010
|
||||
@Shane:
|
||||
|
||||
[systemd] does too many things
|
||||
It manages the startup and lifetime of system processes. That's it.
|
||||
|
||||
From the article you linked:
|
||||
Merging periodically run jobs into the main system process doesn't make sense.
|
||||
|
||||
Why not? "cron" and "at" manage the startup of periodic system processes. The only thing they do different from "init" is that they start the processes at a time other than bootup. Everything else is common between them. So why not de-duplicate the effort involved in starting, tracking and logging, and just allow "init" to start other processes at times other than boot?
|
||||
|
||||
Replacing a simple /etc/crontab text file with multiple, awkwardly named XML plist files scattered among no less than four different directories is taking two big steps toward complexity.
|
||||
|
||||
There's no reason that systemd would be implemented that badly. In fact, I'm pretty sure that systemd reads existing "crontab" files just fine. So systemd doesn't require any changes there.
|
||||
|
||||
Starting infrequently used on-demand socket-based daemons from launchd seems like it could open the main system process to a potential denial of service attack. I have not explored this idea or researched to see if it has already been tried,
|
||||
|
||||
Well, I haven't researched it, that looks like nothing more than FUD and making-shit-up to me.
|
||||
|
||||
One of the core principles of Unix programing is do one thing and do it well.
|
||||
|
||||
Like having one and only one place to consistently manage the startup and monitoring of system processes? Oh yeah, that's totally anti-Unix-philosophy.
|
||||
|
||||
Posted by Lennart at Tue Aug 24 19:37:50 2010
|
||||
Denice, __Linux is a scalabale operating system__. It is used on big irons to tiniest devices. With systemd we try to cover the whole bandwidth, and please understand that your specific use case is not the only one we need to cover.
|
||||
|
||||
Shane, you are right, systemd is nothing like traditional Unix. And that is a good thing. Unix has been designed 41 years ago. You honestly believe that its design is perfect and flawless and 41 years after it was designed still should be followed in all detail? No, computers changed, and Unix never was perfect. It probably was a better design than most other operating systems, but this does not mean it is perfect and we should never depart from it. systemd is inspired by Unix, but also from what has been done on MacOS and even on the Windows world, and on Solaris. We didn't copy any of the existing services 1:1, we just let us inspire by their best features and translated them to Linux and added quite a bit of new stuff on top. And that's how it should be done. Unix is an inspiration, it is not the holy grail. Not 41y after it was designed.
|
||||
|
||||
The fact that on traditional Unix the init system was seperate from cron, from at, from inetd, from the dbus service activator and from everything else meant that all of them reimplemented a big chunk of their code, i.e. what was involved with spawning processes. It was a useless code duplication, and all implementations sucked at it in one way or another. Also, you could not run the same thing from more than one of these systems without manually ensuring that things would happen race-freely and properly ordered. In systemd we unified all of this. We use the same codepaths for spawning processes, regardless if they are started via timers, via sockets, via busses, at boot-up, via devices and so on. This allows us to reduce the amount of code duplication, and provide the same awesome process babysitting to all triggers. And that is a big big advantage. If you look at the systemd source code you will notice that the remaining amount of code, for example for doing timer-based spawning is actually very very short, less than 500 lines (including comments and whitespace!). So overall, we simplify things drastically, we get rid of immense code duplication, and we still are a lot more powerful than what came before.
|
||||
|
||||
So, in summary: just because we do things differently doesn't mean we do it worse.
|
||||
|
||||
And if you tell me that systemd is not Unixy, then I can only agree, and I don't feel ashamed at all of that. Because my horizon is much further than just Unix.
|
||||
|
||||
Posted by Lennart at Mon Jul 11 15:22:01 2011
|
||||
Rob, this would surprise me too if it was true. But... I actually wrote such a blog article:
|
||||
|
||||
http://0pointer.de/blog/projects/systemd-for-admins-3.html
|
||||
333
Zim/Utils/systemd/systemd_for_Administrators,_Part_II.txt
Normal file
@@ -0,0 +1,333 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-21T20:12:53+08:00
|
||||
|
||||
====== systemd for Administrators, Part II ======
|
||||
Created Wednesday 21 November 2012
|
||||
|
||||
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
|
||||
|
||||
Wed, 08 Sep 2010
|
||||
systemd for Administrators, Part II
|
||||
|
||||
Here's the second installment of my ongoing series about systemd for administrators.
|
||||
|
||||
===== Which Service Owns Which Processes? =====
|
||||
|
||||
On most Linux systems the number of processes that are running by default is substantial. Knowing __which process does what and where it belongs to__ becomes increasingly difficult. Some services even maintain a couple of worker processes which clutter the "ps" output with many additional processes that are often not easy to recognize. This is further complicated if daemons spawn arbitrary 3rd-party processes, as Apache does with CGI processes, or cron does with user jobs.
|
||||
|
||||
A slight remedy for this is often the __process inheritance tree__, as shown by "ps xaf". However this is usually not reliable, as processes whose parents die get reparented to PID 1, and hence all information about inheritance gets lost. If a process "double forks" it hence loses its relationships to the processes that started it. (This actually is supposed to be a feature and is relied on for the traditional Unix daemonizing logic.) Furthermore processes can freely change their names with PR_SETNAME or by patching argv[0], thus making it harder to recognize them. In fact they can play hide-and-seek with the administrator pretty nicely this way.
|
||||
|
||||
In systemd we __place every process that is spawned in a control group named after its service__. Control groups (or cgroups) at their most basic are simply groups of processes that can be arranged in a hierarchy and labelled individually. When processes spawn other processes these children are automatically made members of the parents cgroup. Leaving a cgroup is not possible for unprivileged processes. Thus, cgroups can be used as **an effective way to label processes** after the service they belong to and be sure that the service cannot escape from the label, regardless how often it forks or renames itself. Furthermore this can be used to safely __kill a service and all processes it created__, again with no chance of escaping.
|
||||
|
||||
In today's installment I want to introduce you to two commands you may use to relate systemd services and processes. The first one, is the well known ps command which has been updated to show cgroup information along the other process details. And this is how it looks:
|
||||
|
||||
**$ ps xawf -eo pid,user,cgroup,args**
|
||||
PID USER CGROUP COMMAND
|
||||
2 root - [kthreadd]
|
||||
3 root - \_ [ksoftirqd/0]
|
||||
[...]
|
||||
4281 root - \_ [flush-8:0]
|
||||
1 root name=systemd:/systemd-1 /sbin/init
|
||||
455 root name=systemd:/systemd-1/sysinit.service /sbin/udevd -d
|
||||
28188 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
|
||||
28191 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
|
||||
1096 dbus name=systemd:/systemd-1/dbus.service /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
|
||||
1131 root name=systemd:/systemd-1/auditd.service auditd
|
||||
1133 root name=systemd:/systemd-1/auditd.service \_ /sbin/audispd
|
||||
1135 root name=systemd:/systemd-1/auditd.service \_ /usr/sbin/sedispatch
|
||||
1171 root name=systemd:/systemd-1/NetworkManager.service /usr/sbin/NetworkManager --no-daemon
|
||||
4028 root name=systemd:/systemd-1/NetworkManager.service \_ /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -
|
||||
1175 avahi name=systemd:/systemd-1/avahi-daemon.service avahi-daemon: running [epsilon.local]
|
||||
1194 avahi name=systemd:/systemd-1/avahi-daemon.service \_ avahi-daemon: chroot helper
|
||||
1193 root name=systemd:/systemd-1/rsyslog.service /sbin/rsyslogd -c 4
|
||||
1195 root name=systemd:/systemd-1/cups.service cupsd -C /etc/cups/cupsd.conf
|
||||
1207 root name=systemd:/systemd-1/mdmonitor.service mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
|
||||
1210 root name=systemd:/systemd-1/irqbalance.service irqbalance
|
||||
1216 root name=systemd:/systemd-1/dbus.service /usr/sbin/modem-manager
|
||||
1219 root name=systemd:/systemd-1/dbus.service /usr/libexec/polkit-1/polkitd
|
||||
1242 root name=systemd:/systemd-1/dbus.service /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
|
||||
1249 68 name=systemd:/systemd-1/haldaemon.service hald
|
||||
1250 root name=systemd:/systemd-1/haldaemon.service \_ hald-runner
|
||||
1273 root name=systemd:/systemd-1/haldaemon.service \_ hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
|
||||
1275 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-rfkill-killswitch
|
||||
1284 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-leds
|
||||
1285 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-generic-backlight
|
||||
1287 68 name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-acpi
|
||||
1317 root name=systemd:/systemd-1/abrtd.service /usr/sbin/abrtd -d -s
|
||||
1332 root name=systemd:/systemd-1/getty@.service/tty2 /sbin/mingetty tty2
|
||||
1339 root name=systemd:/systemd-1/getty@.service/tty3 /sbin/mingetty tty3
|
||||
1342 root name=systemd:/systemd-1/getty@.service/tty5 /sbin/mingetty tty5
|
||||
1343 root name=systemd:/systemd-1/getty@.service/tty4 /sbin/mingetty tty4
|
||||
1344 root name=systemd:/systemd-1/crond.service crond
|
||||
1346 root name=systemd:/systemd-1/getty@.service/tty6 /sbin/mingetty tty6
|
||||
1362 root name=systemd:/systemd-1/sshd.service /usr/sbin/sshd
|
||||
1376 root name=systemd:/systemd-1/prefdm.service /usr/sbin/gdm-binary -nodaemon
|
||||
1391 root name=systemd:/systemd-1/prefdm.service \_ /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
|
||||
1394 root name=systemd:/systemd-1/prefdm.service \_ /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
|
||||
1495 root name=systemd:/user/lennart/1 \_ pam: gdm-password
|
||||
1521 lennart name=systemd:/user/lennart/1 \_ gnome-session
|
||||
1621 lennart name=systemd:/user/lennart/1 \_ metacity
|
||||
1635 lennart name=systemd:/user/lennart/1 \_ gnome-panel
|
||||
1638 lennart name=systemd:/user/lennart/1 \_ nautilus
|
||||
1640 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/polkit-gnome-authentication-agent-1
|
||||
1641 lennart name=systemd:/user/lennart/1 \_ /usr/bin/seapplet
|
||||
1644 lennart name=systemd:/user/lennart/1 \_ gnome-volume-control-applet
|
||||
1646 lennart name=systemd:/user/lennart/1 \_ /usr/sbin/restorecond -u
|
||||
1652 lennart name=systemd:/user/lennart/1 \_ /usr/bin/devilspie
|
||||
1662 lennart name=systemd:/user/lennart/1 \_ nm-applet --sm-disable
|
||||
1664 lennart name=systemd:/user/lennart/1 \_ gnome-power-manager
|
||||
1665 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/gdu-notification-daemon
|
||||
1670 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/evolution/2.32/evolution-alarm-notify
|
||||
1672 lennart name=systemd:/user/lennart/1 \_ /usr/bin/python /usr/share/system-config-printer/applet.py
|
||||
1674 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/deja-dup/deja-dup-monitor
|
||||
1675 lennart name=systemd:/user/lennart/1 \_ abrt-applet
|
||||
1677 lennart name=systemd:/user/lennart/1 \_ bluetooth-applet
|
||||
1678 lennart name=systemd:/user/lennart/1 \_ gpk-update-icon
|
||||
1408 root name=systemd:/systemd-1/console-kit-daemon.service /usr/sbin/console-kit-daemon --no-daemon
|
||||
1419 gdm name=systemd:/systemd-1/prefdm.service /usr/bin/dbus-launch --exit-with-session
|
||||
1453 root name=systemd:/systemd-1/dbus.service /usr/libexec/upowerd
|
||||
1473 rtkit name=systemd:/systemd-1/rtkit-daemon.service /usr/libexec/rtkit-daemon
|
||||
1496 root name=systemd:/systemd-1/accounts-daemon.service /usr/libexec/accounts-daemon
|
||||
1499 root name=systemd:/systemd-1/systemd-logger.service /lib/systemd/systemd-logger
|
||||
1511 lennart name=systemd:/systemd-1/prefdm.service /usr/bin/gnome-keyring-daemon --daemonize --login
|
||||
1534 lennart name=systemd:/user/lennart/1 dbus-launch --sh-syntax --exit-with-session
|
||||
1535 lennart name=systemd:/user/lennart/1 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
|
||||
1603 lennart name=systemd:/user/lennart/1 /usr/libexec/gconfd-2
|
||||
1612 lennart name=systemd:/user/lennart/1 /usr/libexec/gnome-settings-daemon
|
||||
1615 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd
|
||||
1626 lennart name=systemd:/user/lennart/1 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
|
||||
1634 lennart name=systemd:/user/lennart/1 /usr/bin/pulseaudio --start --log-target=syslog
|
||||
1649 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/pulse/gconf-helper
|
||||
1645 lennart name=systemd:/user/lennart/1 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
|
||||
1668 lennart name=systemd:/user/lennart/1 /usr/libexec/im-settings-daemon
|
||||
1701 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-gdu-volume-monitor
|
||||
1707 lennart name=systemd:/user/lennart/1 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
|
||||
1725 lennart name=systemd:/user/lennart/1 /usr/libexec/clock-applet
|
||||
1727 lennart name=systemd:/user/lennart/1 /usr/libexec/wnck-applet
|
||||
1729 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-area-applet
|
||||
1733 root name=systemd:/systemd-1/dbus.service /usr/libexec/udisks-daemon
|
||||
1747 root name=systemd:/systemd-1/dbus.service \_ udisks-daemon: polling /dev/sr0
|
||||
1759 lennart name=systemd:/user/lennart/1 gnome-screensaver
|
||||
1780 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
|
||||
1864 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-afc-volume-monitor
|
||||
1874 lennart name=systemd:/user/lennart/1 /usr/libexec/gconf-im-settings-daemon
|
||||
1903 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
|
||||
1909 lennart name=systemd:/user/lennart/1 gnome-terminal
|
||||
1913 lennart name=systemd:/user/lennart/1 \_ gnome-pty-helper
|
||||
1914 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
29231 lennart name=systemd:/user/lennart/1 | \_ ssh tango
|
||||
2221 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
4193 lennart name=systemd:/user/lennart/1 | \_ ssh tango
|
||||
2461 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
29219 lennart name=systemd:/user/lennart/1 | \_ emacs systemd-for-admins-1.txt
|
||||
15113 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
27251 lennart name=systemd:/user/lennart/1 \_ empathy
|
||||
29504 lennart name=systemd:/user/lennart/1 \_ ps xawf -eo pid,user,cgroup,args
|
||||
1968 lennart name=systemd:/user/lennart/1 ssh-agent
|
||||
1994 lennart name=systemd:/user/lennart/1 gpg-agent --daemon --write-env-file
|
||||
18679 lennart name=systemd:/user/lennart/1 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
|
||||
18741 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/firefox-3.6/firefox
|
||||
28900 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
|
||||
4016 root name=systemd:/systemd-1/sysinit.service /usr/sbin/bluetoothd --udev
|
||||
4094 smmsp name=systemd:/systemd-1/sendmail.service sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
|
||||
4096 root name=systemd:/systemd-1/sendmail.service sendmail: accepting connections
|
||||
4112 ntp name=systemd:/systemd-1/ntpd.service /usr/sbin/ntpd -n -u ntp:ntp -g
|
||||
27262 lennart name=systemd:/user/lennart/1 /usr/libexec/mission-control-5
|
||||
27265 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-haze
|
||||
27268 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-logger
|
||||
27270 lennart name=systemd:/user/lennart/1 /usr/libexec/dconf-service
|
||||
27280 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-daemon
|
||||
27284 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-gabble
|
||||
27285 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-salut
|
||||
27297 lennart name=systemd:/user/lennart/1 /usr/libexec/geoclue-yahoo
|
||||
|
||||
(Note that this output is shortened, I have removed most of the kernel threads here, since they are not relevant in the context of this blog story)
|
||||
|
||||
In the third column you see the cgroup systemd assigned to each process. You'll find that the udev processes are in the **name=systemd:/systemd-1/sysinit.service** cgroup, which is where systemd places **all processes started by the sysinit.service** service, which covers early boot.
|
||||
|
||||
My personal recommendation is to set the shell alias psc to the ps command line shown above:
|
||||
|
||||
**alias psc='ps xawf -eo pid,user,cgroup,args'**
|
||||
|
||||
With this service information of processes is just four keypresses away!
|
||||
|
||||
A different way to present the same information is the __systemd-cgls__ tool we ship with systemd. It shows the cgroup hierarchy in a pretty tree. Its output looks like this:
|
||||
|
||||
$ systemd-cgls
|
||||
+ 2 [kthreadd]
|
||||
[...]
|
||||
+ 4281 [flush-8:0]
|
||||
+ user
|
||||
| \ lennart
|
||||
| \ 1
|
||||
| + 1495 pam: gdm-password
|
||||
| + 1521 gnome-session
|
||||
| + 1534 dbus-launch --sh-syntax --exit-with-session
|
||||
| + 1535 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
|
||||
| + 1603 /usr/libexec/gconfd-2
|
||||
| + 1612 /usr/libexec/gnome-settings-daemon
|
||||
| + 1615 /ushr/libexec/gvfsd
|
||||
| + 1621 metacity
|
||||
| + 1626 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
|
||||
| + 1634 /usr/bin/pulseaudio --start --log-target=syslog
|
||||
| + 1635 gnome-panel
|
||||
| + 1638 nautilus
|
||||
| + 1640 /usr/libexec/polkit-gnome-authentication-agent-1
|
||||
| + 1641 /usr/bin/seapplet
|
||||
| + 1644 gnome-volume-control-applet
|
||||
| + 1645 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
|
||||
| + 1646 /usr/sbin/restorecond -u
|
||||
| + 1649 /usr/libexec/pulse/gconf-helper
|
||||
| + 1652 /usr/bin/devilspie
|
||||
| + 1662 nm-applet --sm-disable
|
||||
| + 1664 gnome-power-manager
|
||||
| + 1665 /usr/libexec/gdu-notification-daemon
|
||||
| + 1668 /usr/libexec/im-settings-daemon
|
||||
| + 1670 /usr/libexec/evolution/2.32/evolution-alarm-notify
|
||||
| + 1672 /usr/bin/python /usr/share/system-config-printer/applet.py
|
||||
| + 1674 /usr/lib64/deja-dup/deja-dup-monitor
|
||||
| + 1675 abrt-applet
|
||||
| + 1677 bluetooth-applet
|
||||
| + 1678 gpk-update-icon
|
||||
| + 1701 /usr/libexec/gvfs-gdu-volume-monitor
|
||||
| + 1707 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
|
||||
| + 1725 /usr/libexec/clock-applet
|
||||
| + 1727 /usr/libexec/wnck-applet
|
||||
| + 1729 /usr/libexec/notification-area-applet
|
||||
| + 1759 gnome-screensaver
|
||||
| + 1780 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
|
||||
| + 1864 /usr/libexec/gvfs-afc-volume-monitor
|
||||
| + 1874 /usr/libexec/gconf-im-settings-daemon
|
||||
| + 1882 /usr/libexec/gvfs-gphoto2-volume-monitor
|
||||
| + 1903 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
|
||||
| + 1909 gnome-terminal
|
||||
| + 1913 gnome-pty-helper
|
||||
| + 1914 bash
|
||||
| + 1968 ssh-agent
|
||||
| + 1994 gpg-agent --daemon --write-env-file
|
||||
| + 2221 bash
|
||||
| + 2461 bash
|
||||
| + 4193 ssh tango
|
||||
| + 15113 bash
|
||||
| + 18679 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
|
||||
| + 18741 /usr/lib64/firefox-3.6/firefox
|
||||
| + 27251 empathy
|
||||
| + 27262 /usr/libexec/mission-control-5
|
||||
| + 27265 /usr/libexec/telepathy-haze
|
||||
| + 27268 /usr/libexec/telepathy-logger
|
||||
| + 27270 /usr/libexec/dconf-service
|
||||
| + 27280 /usr/libexec/notification-daemon
|
||||
| + 27284 /usr/libexec/telepathy-gabble
|
||||
| + 27285 /usr/libexec/telepathy-salut
|
||||
| + 27297 /usr/libexec/geoclue-yahoo
|
||||
| + 28900 /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
|
||||
| + 29219 emacs systemd-for-admins-1.txt
|
||||
| + 29231 ssh tango
|
||||
| \ 29519 systemd-cgls
|
||||
\ systemd-1
|
||||
+ 1 /sbin/init
|
||||
+ ntpd.service
|
||||
| \ 4112 /usr/sbin/ntpd -n -u ntp:ntp -g
|
||||
+ systemd-logger.service
|
||||
| \ 1499 /lib/systemd/systemd-logger
|
||||
+ accounts-daemon.service
|
||||
| \ 1496 /usr/libexec/accounts-daemon
|
||||
+ rtkit-daemon.service
|
||||
| \ 1473 /usr/libexec/rtkit-daemon
|
||||
+ console-kit-daemon.service
|
||||
| \ 1408 /usr/sbin/console-kit-daemon --no-daemon
|
||||
+ prefdm.service
|
||||
| + 1376 /usr/sbin/gdm-binary -nodaemon
|
||||
| + 1391 /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
|
||||
| + 1394 /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
|
||||
| + 1419 /usr/bin/dbus-launch --exit-with-session
|
||||
| \ 1511 /usr/bin/gnome-keyring-daemon --daemonize --login
|
||||
+ getty@.service
|
||||
| + tty6
|
||||
| | \ 1346 /sbin/mingetty tty6
|
||||
| + tty4
|
||||
| | \ 1343 /sbin/mingetty tty4
|
||||
| + tty5
|
||||
| | \ 1342 /sbin/mingetty tty5
|
||||
| + tty3
|
||||
| | \ 1339 /sbin/mingetty tty3
|
||||
| \ tty2
|
||||
| \ 1332 /sbin/mingetty tty2
|
||||
+ abrtd.service
|
||||
| \ 1317 /usr/sbin/abrtd -d -s
|
||||
+ crond.service
|
||||
| \ 1344 crond
|
||||
+ sshd.service
|
||||
| \ 1362 /usr/sbin/sshd
|
||||
+ sendmail.service
|
||||
| + 4094 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
|
||||
| \ 4096 sendmail: accepting connections
|
||||
+ haldaemon.service
|
||||
| + 1249 hald
|
||||
| + 1250 hald-runner
|
||||
| + 1273 hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
|
||||
| + 1275 /usr/libexec/hald-addon-rfkill-killswitch
|
||||
| + 1284 /usr/libexec/hald-addon-leds
|
||||
| + 1285 /usr/libexec/hald-addon-generic-backlight
|
||||
| \ 1287 /usr/libexec/hald-addon-acpi
|
||||
+ irqbalance.service
|
||||
| \ 1210 irqbalance
|
||||
+ avahi-daemon.service
|
||||
| + 1175 avahi-daemon: running [epsilon.local]
|
||||
+ NetworkManager.service
|
||||
| + 1171 /usr/sbin/NetworkManager --no-daemon
|
||||
| \ 4028 /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -cf /var/run/nm-dhclient-wlan0.conf wlan0
|
||||
+ rsyslog.service
|
||||
| \ 1193 /sbin/rsyslogd -c 4
|
||||
+ mdmonitor.service
|
||||
| \ 1207 mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
|
||||
+ cups.service
|
||||
| \ 1195 cupsd -C /etc/cups/cupsd.conf
|
||||
+ auditd.service
|
||||
| + 1131 auditd
|
||||
| + 1133 /sbin/audispd
|
||||
| \ 1135 /usr/sbin/sedispatch
|
||||
+ dbus.service
|
||||
| + 1096 /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
|
||||
| + 1216 /usr/sbin/modem-manager
|
||||
| + 1219 /usr/libexec/polkit-1/polkitd
|
||||
| + 1242 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
|
||||
| + 1453 /usr/libexec/upowerd
|
||||
| + 1733 /usr/libexec/udisks-daemon
|
||||
| + 1747 udisks-daemon: polling /dev/sr0
|
||||
| \ 29509 /usr/libexec/packagekitd
|
||||
+ dev-mqueue.mount
|
||||
+ dev-hugepages.mount
|
||||
\ sysinit.service
|
||||
+ 455 /sbin/udevd -d
|
||||
+ 4016 /usr/sbin/bluetoothd --udev
|
||||
+ 28188 /sbin/udevd -d
|
||||
\ 28191 /sbin/udevd -d
|
||||
|
||||
(This too is shortened, the same way)
|
||||
|
||||
As you can see, this command shows the processes by their cgroup and hence service, as systemd labels the cgroups after the services. For example, you can easily see that the auditing service auditd.service spawns three individual processes, auditd, audisp and sedispatch.
|
||||
|
||||
If you look closely you will notice that a number of processes have been assigned to the cgroup **/user/1**. At this point let's simply leave it at that __systemd not only maintains services in cgroups, but user session processes as well__. In a later installment we'll discuss in more detail what this about.
|
||||
|
||||
So much for now, come back soon for the next installment!
|
||||
|
||||
posted at: 00:52 | path: /projects | permanent link to this entry | 13 comments
|
||||
Posted by liam at Wed Sep 8 04:51:28 2010
|
||||
Thanks for these posts.
|
||||
I'm a bit uncertain as to how far cgroups can be pushed for administrative purposes. Can you have nested cgroups? For instance, a Gnome/X/whatever group that one could kill? Can the end user create alias' for cgroups which could then aggregate them into more manageable units?
|
||||
|
||||
thanks
|
||||
|
||||
Posted by Lennart at Wed Sep 8 11:36:25 2010
|
||||
Liam, cgroups are fully recursive, you may split every cgroup into sub-cgroups. And as soon as __systemd is used for session management__ the same way it is used for system management session services will be arranged the same way in subgroups of the group the session manager happened to be executed under.
|
||||
|
||||
Posted by Perry Lorier at Sun Sep 12 19:57:12 2010
|
||||
So, you've reinvented process groups?
|
||||
|
||||
Posted by Lennart at Sun Sep 12 20:21:43 2010
|
||||
Perry, no, not at all. process groups you can escape. They aren't hierarchical, they cannot be labelled. Process groups are very very different from cgroups, and useful for little more than pipeline building in shells.
|
||||
|
||||
Posted by Ken Stailey at Sat Nov 10 20:45:39 2012
|
||||
The ps "ax" and "-e" options both enable displaying "everything", i.e. all processes. It is not necessary to use both.
|
||||
250
Zim/Utils/systemd/systemd_for_Administrators,_Part_III.txt
Normal file
@@ -0,0 +1,250 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-21T20:36:45+08:00
|
||||
|
||||
====== systemd for Administrators, Part III ======
|
||||
Created Wednesday 21 November 2012
|
||||
|
||||
|
||||
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
|
||||
|
||||
Fri, 01 Oct 2010
|
||||
systemd for Administrators, Part III
|
||||
|
||||
Here's the third installment of my ongoing series about systemd for administrators.
|
||||
|
||||
===== How Do I Convert A SysV Init Script Into A systemd Service File? =====
|
||||
|
||||
Traditionally, Unix and Linux services (daemons) are started via __SysV init scripts__. These are Bourne Shell scripts, usually residing in a directory such as __/etc/rc.d/init.d/__ which when called with one of a few standardized arguments (verbs) such as __start, stop or restart__ controls, i.e. starts, stops or restarts the service in question. For starts this usually involves invoking the daemon binary, which then forks a background process (more precisely daemonizes).
|
||||
|
||||
Shell scripts tend to be slow, needlessly hard to read, very verbose and fragile. Although they are __immensly flexible__ (after all, they are just code) some things are very hard to do properly with shell scripts, such as ordering parallized execution, correctly supervising processes or just **configuring execution contexts** in all detail. systemd provides __compatibility__ with these shell scripts, but due to the shortcomings pointed out it is recommended to install native systemd service files for all daemons installed. Also, in contrast to SysV init scripts which have to be adjusted to the distribution systemd service files are compatible with any kind of distribution running systemd (which become more and more these days...).
|
||||
|
||||
What follows is a terse guide how to take a SysV init script and translate it into a native systemd service file. Ideally, upstream projects should ship and install systemd service files in their tarballs. If you have successfully converted a SysV script according to the guidelines it might hence be a good idea to submit the file as patch to upstream. How to prepare a patch like that will be discussed in a later installment, suffice to say at this point that the daemon(7) manual page shipping with systemd contains a lot of useful information regarding this.
|
||||
|
||||
So, let's jump right in. As an example we'll convert the init script of the **ABRT** daemon into a systemd service file. ABRT is a standard component of every Fedora install, and is an acronym for Automatic Bug Reporting Tool, which pretty much describes what it does, i.e. it is a service for collecting crash dumps. Its SysV script I have uploaded here.
|
||||
|
||||
The first step when converting such a script is to read it (surprise surprise!) and distill the useful information from the usually pretty long script. In almost all cases the script consists of mostly boilerplate code that is identical or at least very similar in all init scripts, and usually copied and pasted from one to the other. So, let's extract the interesting information from the script linked above:
|
||||
|
||||
* A description string for the service is "Daemon to detect crashing apps". As it turns out, the header comments include a redundant number of description strings, some of them describing less the actual service but the init script to start it. systemd services include a description too, and it should describe the service and not the service file.
|
||||
* The __LSB header__[1] contains dependency information. systemd due to its design around socket-based activation usually needs __no__ (or very little) manually configured dependencies. (For details regarding socket activation see the original announcement blog post.) In this case the dependency on $syslog (which encodes that abrtd requires a syslog daemon), is the only valuable information. While the header lists another dependency ($local_fs) this one is redundant with systemd as normal system services are always started with all local file systems available.
|
||||
* The LSB header suggests that this service should be started in runlevels 3 (multi-user) and 5 (graphical).
|
||||
* The daemon binary is /usr/sbin/abrtd
|
||||
|
||||
And that's already it. The entire remaining content of this 115-line shell script is simply boilerplate or otherwise redundant code: code that deals with synchronizing and serializing startup (i.e. the code regarding lock files) or that outputs status messages (i.e. the code calling echo), or simply parsing of the verbs (i.e. the big case block).
|
||||
|
||||
From the information extracted above we can now write our systemd service file:
|
||||
|
||||
**[Unit]**
|
||||
**Description=Daemon to detect crashing apps**
|
||||
**After=syslog.target**
|
||||
|
||||
**[Service]**
|
||||
**ExecStart=/usr/sbin/abrtd**
|
||||
**Type=forking**
|
||||
|
||||
**[Install]**
|
||||
**WantedBy=multi-user.target**
|
||||
|
||||
A little explanation of the contents of this file: The [Unit] section contains generic information about the service. systemd not only manages system services, but also devices, mount points, timer, and other components of the system. The generic term for all these objects in systemd is a unit, and the [Unit] section encodes information about it that might be applicable not only to services but also in to the other unit types systemd maintains. In this case we set the following unit settings: we set the description string and configure that the daemon shall be **started after** Syslog[2], similar to what is encoded in the LSB header of the original init script. For this Syslog dependency we create a dependency of type __After=__ on a systemd unit syslog.target. The latter is **a special target unit** in systemd and is the standardized name to pull in a syslog implementation. For more information about these standardized names see the systemd.special(7). Note that a dependency of type After= only encodes the suggested ordering, but does not actually cause syslog to be started when abrtd is -- and this is exactly what we want, since abrtd actually works fine even without syslog being around. However, if both are started (and usually they are) then the order in which they are is controlled with this dependency.
|
||||
|
||||
The next section is [Service] which encodes information about the service itself. It contains all those settings that apply only to services, and not the other kinds of units systemd maintains (mount points, devices, timers, ...). Two settings are used here: __ExecStart=__ takes the path to the binary to execute when the service shall be started up. And with __Type=__ we configure **how the service notifies the init system that it finished starting up.** Since traditional Unix daemons do this by returning to the parent process after having forked off and initialized the background daemon we set the type to forking here. That tells systemd to wait until the start-up binary returns and then consider the processes still running afterwards the daemon processes.
|
||||
|
||||
The final section is [Install]. It encodes information about how the suggested installation should look like, i.e. under which circumstances and by which triggers the service shall be started. In this case we simply say that __this service shall be started when the multi-user.target unit is activated__. This is a special unit (see above) that basically takes the role of the classic SysV Runlevel 3[3]. The setting WantedBy= has little effect on the daemon during runtime. It is only read by the systemctl enable command, which is the recommended way to enable a service in systemd. This command will simply ensure that our little service gets automatically activated as soon as multi-user.target is requested, which it is on all normal boots[4].
|
||||
|
||||
And that's it. Now we already have a minimal working systemd service file. To test it we copy it to /etc/systemd/system/abrtd.service and invoke systemctl daemon-reload. This will make systemd take notice of it, and now we can start the service with it: systemctl start abrtd.service. We can verify the status via systemctl status abrtd.service. And we can stop it again via systemctl stop abrtd.service. Finally, we can enable it, so that it is activated by default on future boots with systemctl enable abrtd.service.
|
||||
|
||||
The service file above, while sufficient and basically a 1:1 translation (feature- and otherwise) of the SysV init script still has room for improvement. Here it is a little bit updated:
|
||||
|
||||
[Unit]
|
||||
Description=ABRT Automated Bug Reporting Tool
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=com.redhat.abrt
|
||||
ExecStart=/usr/sbin/abrtd -d -s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
So, what did we change? Two things: we improved the description string a bit. More importantly however, we changed the type of the service to dbus and configured the D-Bus bus name of the service. Why did we do this? As mentioned classic SysV services daemonize after startup, which usually involves double forking and detaching from any terminal. While this is useful and necessary when daemons are invoked via a script, this is unnecessary (and slow) as well as counterproductive when a proper process babysitter such as systemd is used. The reason for that is that the forked off daemon process usually has little relation to the original process started by systemd (after all the daemonizing scheme's whole idea is to remove this relation), and hence it is difficult for systemd to figure out after the fork is finished which process belonging to the service is actually the main process and which processes might just be auxiliary. But that information is crucial to implement advanced babysitting, i.e. supervising the process, automatic respawning on abnormal termination, collectig crash and exit code information and suchlike. In order to make it easier for systemd to figure out the main process of the daemon we changed the service type to dbus. The semantics of this service type are appropriate for all services that take a name on the D-Bus system bus as last step of their initialization[5]. ABRT is one of those. With this setting systemd will spawn the ABRT process, which will no longer fork (this is configured via the -d -s switches to the daemon), and systemd will consider the service fully started up as soon as com.redhat.abrt appears on the bus. This way the process spawned by systemd is the main process of the daemon, systemd has a reliable way to figure out when the daemon is fully started up and systemd can easily supervise it.
|
||||
|
||||
And that's all there is to it. We have a simple systemd service file now that encodes in 10 lines more information than the original SysV init script encoded in 115. And even now there's a lot of room left for further improvement utilizing more features systemd offers. For example, we could set Restart=restart-always to tell systemd to automatically restart this service when it dies. Or, we could use OOMScoreAdjust=-500 to ask the kernel to please leave this process around when the OOM killer wreaks havoc. Or, we could use CPUSchedulingPolicy=idle to ensure that abrtd processes crash dumps in background only, always allowing the kernel to give preference to whatever else might be running and needing CPU time.
|
||||
|
||||
For more information about the configuration options mentioned here, see the respective man pages systemd.unit(5), systemd.service(5), systemd.exec(5). Or, browse all of systemd's man pages.
|
||||
|
||||
Of course, not all SysV scripts are as easy to convert as this one. But gladly, as it turns out the vast majority actually are.
|
||||
|
||||
That's it for today, come back soon for the next installment in our series.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] The LSB header of init scripts is a convention of including meta data about the service in comment blocks at the top of SysV init scripts and is defined by the Linux Standard Base. This was intended to standardize init scripts between distributions. While most distributions have adopted this scheme, the handling of the headers varies greatly between the distributions, and in fact still makes it necessary to adjust init scripts for every distribution. As such the LSB spec never kept the promise it made.
|
||||
|
||||
[2] Strictly speaking, this dependency does not even have to be encoded here, as it is redundant in a system where the Syslog daemon is socket activatable. Modern syslog systems (for example rsyslog v5) have been patched upstream to be socket-activatable. If such a init system is used configuration of the After=syslog.target dependency is redundant and implicit. However, to maintain compatibility with syslog services that have not been updated we include this dependency here.
|
||||
|
||||
[3] At least how it used to be defined on Fedora.
|
||||
|
||||
[4] Note that in systemd the graphical bootup (graphical.target, taking the role of SysV runlevel 5) is an implicit superset of the console-only bootup (multi-user.target, i.e. like runlevel 3). That means hooking a service into the latter will also hook it into the former.
|
||||
|
||||
[5] Actually the majority of services of the default Fedora install now take a name on the bus after startup.
|
||||
|
||||
posted at: 04:42 | path: /projects | permanent link to this entry | 19 comments
|
||||
Posted by Anonymous at Fri Oct 1 06:58:25 2010
|
||||
Ideally, couldn't you configure ABRT to only run when core files show up in a given directory, or when something requests its dbus service?
|
||||
|
||||
Posted by drago01 at Fri Oct 1 10:52:20 2010
|
||||
CPUSchedulingPolicy=idle ... is there the same thing for IO i.e IOSchedulingPolicy=idle ?
|
||||
|
||||
In most cases I couldn't care less about CPU on todays multicore machines but IO is still a very limited resource (when not running an SSD).
|
||||
|
||||
The kernel actually allows setting IO priorities (when using the CFQ scheduler).
|
||||
|
||||
Posted by Lennart at Fri Oct 1 13:04:51 2010
|
||||
Anonymous: While this would definitely be desirable AFAICS abrt doesn't support this scheme, since it needs to be running when the first crash dump is collected.
|
||||
|
||||
drag01: There's IOSchedulingClass=idle for you.
|
||||
|
||||
Posted by John Drinkwater at Fri Oct 1 13:34:29 2010
|
||||
Restart=restart-always
|
||||
Again, why have this redundancy if you are starting a design from scratch?
|
||||
Restart=always|once|on-success
|
||||
|
||||
CPUSchedulingPolicy=idle
|
||||
IOSchedulingClass=idle
|
||||
Why is one a class, and another a policy? People will mistype these.
|
||||
|
||||
This is not bikeshedding, this is a request to stop making everything long-winded when it does not need to be so. If systemd is to be around for the next few decades, and you have time to refine it before the next Fedora release, please do so.
|
||||
|
||||
Posted by Lennart at Fri Oct 1 13:55:07 2010
|
||||
John, regarding Restart= you have a point. And I fixed that now.
|
||||
|
||||
Regarding the Class vs. Policy thing: that's how the kernel calls these things, blame the kernel folks for that. I think it would be a very bad idea to introduce deviating terminology here where the kernel fucked up.
|
||||
|
||||
Posted by Milan Bouchet-Valat at Fri Oct 1 15:00:38 2010
|
||||
Glad to see you have an easy to parse Description field! But while you're at it, could you consider providing translated descriptions for configuration tools?
|
||||
|
||||
Recently, Ubuntu had a GSoC about writing a new config tool for Upstart. One of the issues was that there's no way to get a localized translation from Upstart jobs or SysV scripts, let alone an icon! It would be great if you tackled this issue in Systemd, e.g. with a standard .desktop-like file that services should ship.
|
||||
|
||||
|
||||
The other part of the work Jacob Peddicord did in his GSoC is more remote from Systemd, but might be interesting. He has a whole project of describing configuration files associated with a service:
|
||||
http://jacob.peddicord.net/gsoc2010/
|
||||
http://people.ubuntu.com/~jpeddicord/SLS/0.8/sls-format-0.8.html
|
||||
|
||||
I guess it can be good you know it exists...
|
||||
|
||||
Posted by Lennart at Fri Oct 1 15:11:55 2010
|
||||
Milan: the longer term plan is to support translations for the descriptions the same way as .desktop files have them. Right now we don't do this, but this is definitely the plan. I am also open to adding an Icon setting, though I am a bit concerned that if we add and Icon, then the next thing asked for is a Vendor ID and so on and so on.
|
||||
|
||||
Posted by j at Fri Oct 1 18:35:14 2010
|
||||
verbosity is redundant (and confusing) for a unix system tool. Since Io scheduling classes are linux-specific, it can be written like that:
|
||||
|
||||
CPUSchedulingPolicy -> SchedLevel
|
||||
IOSchedulingClass -> IOSchedLevel
|
||||
|
||||
BTW is systemd portable to all Unix or it needs linux kernel for some reason?
|
||||
|
||||
Posted by Lennart at Fri Oct 1 18:47:31 2010
|
||||
j, calling the same stuff in userspace differently than in kernelspace, and calling the same stuff in the chrt tool differently than in systemd is a very bad idea.
|
||||
|
||||
systemd is strictly Linux specific. It is not portable to other Unixes and we do not care about portability to them. This allows us to make use of Linux features and is one of the reasons why systemd is so much more powerful than any other init system around.
|
||||
|
||||
Posted by Grahame at Fri Oct 1 19:03:30 2010
|
||||
At the moment if I'm having a problem with a daemon failing to start I might just hack the init script, chuck strace in, and restart it. It'd be great if you could show how you might shim a failing daemon, particularly when debugging 'fails on reboot' issues (eg. starts fine later.)
|
||||
|
||||
Posted by Anonymous at Fri Oct 1 22:10:11 2010
|
||||
I'm wondering about a services that get autostarted via D-Bus. D-Bus starts them itself, so unless I'm wrong they'll end up in the D-Bus service cgroup, not in their own cgroups. Yet I want them to be controllable as services itself. Is this possible to achieve?
|
||||
|
||||
Posted by Michael at Fri Oct 1 23:21:36 2010
|
||||
@Anonymous:
|
||||
|
||||
This is one of systemd's great features:
|
||||
Starting with dbus 1.4.0, dbus-daemon can hand over starting of system services to systemd, where you have all those possibilites to monitor and confine the service (in it's own cgroup)
|
||||
|
||||
All you need to do is to add a
|
||||
SystemdService=foo.service
|
||||
line to the D-Bus service file, create a foo.service file for systemd and systemd will automatically start the service defined in foo.service.
|
||||
|
||||
Posted by Andreas at Sat Oct 2 00:49:51 2010
|
||||
I agree with those complaining about names like CPUSchedulingPolicy but as Lennart said that is hardly the fault of systemd. Not really much that can be done about it.
|
||||
|
||||
This is post is the part I like the most about systemd. No more boilerplate bash and no horrible XML like the launchd plists or overly verbose XML like SMF. Now there might be other good init systems but this is the first one I have seen where it is easy to just read the job configurations.
|
||||
|
||||
Like the use of sections too in the files so when I read them I can mostly ignore sections like [Install].
|
||||
|
||||
Posted by codebeard at Sat Oct 2 04:36:12 2010
|
||||
@Grahame
|
||||
|
||||
I assume that you can do something like:
|
||||
ExecStart=/usr/bin/strace -f -o /root/abrtd.strace /usr/sbin/abrtd -d -s
|
||||
|
||||
But perhaps Lennart has another way in mind to do this?
|
||||
|
||||
Posted by John Drinkwater at Sat Oct 2 14:24:51 2010
|
||||
Lennart, thanks. Apologies if my comment came over a little stronger than I intended.
|
||||
I notice some variables for scheduling have different ranges, is this again a kernel issue? Maybe I should go bang some heads there..
|
||||
|
||||
Posted by Dag Wieers at Mon Nov 22 17:58:46 2010
|
||||
Lennart,
|
||||
|
||||
Since the moment I read your first systemd announcement I am excited about this new development. It's one of those things you wonder why that wasn't done decades ago ;-)
|
||||
|
||||
However, I see one thing that I liked about the sysv scripts, that is not possible. The importance of the original sysv scripts is that they are written in bash and so offers a lot of flexibility to system administrators. Flexibility comes with responsibility :-) However, where in the past sysv scripts did more than simply start/stop/restart/reload, some scripts allowed to check configuration syntax (eg. apache), initialize something (eg. sshd), etc...
|
||||
|
||||
There is an advantage in keeping those actions as part of the systemd tools in my opinion. Even if they are simply passing the action through to a daemon-specific configuration tool (eg. apachectl), which could become a standard. This is exactly why I liked the design of "op" so much (compared to sudo). It provided system administrators (and users) with a single interface to actions using a clean syntax.
|
||||
|
||||
While reading the post and the documentation I couldn't find whether "custom actions" would be retained in your design. If not, what would be the recommended alternative ?
|
||||
|
||||
Posted by Lennart at Mon Nov 22 19:13:05 2010
|
||||
Grahame: codebears is right. You can easily prefix binary paths with strace. Just copy the service file from /lib/systemd/system to /etc/systemd/system and edit the ExecStart= line, and done.
|
||||
|
||||
John: yes, we mostly expose the kernel stuff 1:1.
|
||||
|
||||
Dag: we do not support custom actions, since their set of parameters and what they return is completely free-form it would be a bit weird to pass that through D-Bus. For example, if something is interactive, how would you pass that through D-Bus. If people want additional control interfaces for their tools, then they should create them outside of systemd, for example by creating a seperate <something>ctl tool, such as apachectl. I mean, I think it makes sense to expose new "verbs" in systemd iff these verbs make sense for everybody the same way as "start" and "stop" and similar apply for every service the same way. However, something like "apachectl graceful" is in all its meaning highly specific to Apache, and hence trying to abstract that in systemd must fail, since it's nothing that really could be abstracted nicely. SMF allows definition of additional verbs for each service, but I am not convinced this is really a good idea.
|
||||
|
||||
Posted by anonymous at Thu Jul 14 06:26:29 2011
|
||||
bit confuse with:
|
||||
|
||||
To test it we copy it to /etc/systemd/system/
|
||||
|
||||
in my f15 installation can not find *.service file but i find in /lib/systemd/system
|
||||
|
||||
where .service file actually resident?
|
||||
|
||||
Posted by dave at Mon Feb 27 23:49:34 2012
|
||||
Hi
|
||||
|
||||
I was having problems with my shutdown services not running as expected. I traced the issue to the use of the '--force' flag in the halt, poweroff and reboot services. Here's more about the issue and how to resolve: -
|
||||
|
||||
http://www.practicalclouds.com/content/blog/1/dave-mccormick/2012-02-27/why-do-my-systemd-shutdown-scripts-not-run
|
||||
|
||||
regards
|
||||
|
||||
|
||||
Dave
|
||||
|
||||
Leave a Comment:
|
||||
|
||||
Your Name:
|
||||
|
||||
|
||||
Your E-mail (optional):
|
||||
|
||||
|
||||
Comment:
|
||||
|
||||
|
||||
As a protection against comment spam, please type the following number into the field on the right:
|
||||
Secret Number Image
|
||||
|
||||
Please note that this is neither a support forum nor a bug tracker! Support questions or bug reports posted here will be ignored and not responded to!
|
||||
|
||||
It should be obvious but in case it isn't: the opinions reflected here are my own. They are not the views of my employer, or Ronald McDonald, or anyone else.
|
||||
|
||||
Please note that I take the liberty to delete any comments posted here that I deem inappropriate, off-topic, or insulting. And I excercise this liberty quite agressively. So yes, if you comment here, I might censor you. If you don't want to be censored you are welcome to comment on your own blog instead.
|
||||
Lennart's Blog | Lennart's Homepage | Lennart's Photos | Impressum/Imprint
|
||||
Lennart Poettering <mzoybt (at) 0pointer (dot) net>
|
||||
Syndicated on Planet GNOME, Planet Fedora, planet.freedesktop.org, Planet Debian Upstream. feed RSS 0.91, RSS 2.0
|
||||
Archives: 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
|
||||
Valid XHTML 1.0 Strict! Valid CSS!
|
||||
106
Zim/内核开发/linux_input_ecosystem.txt
Normal file
@@ -0,0 +1,106 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-20T11:48:13+08:00
|
||||
|
||||
====== linux input ecosystem ======
|
||||
Created Tuesday 20 November 2012
|
||||
http://joeshaw.org/2010/10/01/681/
|
||||
|
||||
1 October 2010
|
||||
|
||||
Over the past couple of days, I’ve been trying to figure out how input in Linux works on modern systems. There are lots of small pieces at various levels, and it’s hard to understand how they all interact. Things are not helped by the fact that things have changed quite a bit over the past couple of years as **HAL** — which I helped write — has been giving way to **udev**, and existing literature is largely out of date. This is my attempt at understanding how things work today, in the Ubuntu Lucid release.
|
||||
|
||||
===== kernel =====
|
||||
In the Linux kernel’s **input system**, there are two pieces: __the device driver and the event driver__. The device driver talks to the hardware, obviously. Today, for most USB devices this is handled by **the usbhid driver**. The event drivers handle how to __expose the events generated by the device driver to userspace.__ Today this is primarily done through **evdev**, which creates character devices (typically named **/dev/input/eventN**) and communicates with them through **struct input_event** messages. See include/linux/input.h for its definition.
|
||||
|
||||
A great tool to use for getting information about evdev devices and events is **evtest**.
|
||||
|
||||
A somewhat outdated but still relevant description of the kernel input system can be found in the kernel’s Documentation/input/input.txt file.
|
||||
|
||||
===== udev =====
|
||||
When a device is connected, the kernel creates an entry in **sysfs** for it and generates **a hotplug event**. __That hotplug event is processed by udev__, which applies some policy, attaches additional properties to the device, and ultimately creates a device node for you somewhere in /dev.
|
||||
|
||||
For input devices, the rules in **/lib/udev/rules.d/60-persistent-input.rules** are executed. Among the things it does is run a /**lib/udev/input_id** tool which queries the capabilities of the device from its sysfs node and sets environment variables like **ID_INPUT_KEYBOARD, ID_INPUT_TOUCHPAD, etc.** in the udev database.
|
||||
|
||||
For more information on input_id see the original announcement email to the hotplug list.
|
||||
|
||||
例如:udevadm info 的输出如下
|
||||
P: /devices/platform/i8042/serio4
|
||||
E: DEVPATH=/devices/platform/i8042/serio4
|
||||
E: DRIVER=psmouse
|
||||
E: MODALIAS=serio:ty01pr00id00ex00
|
||||
E: SERIO_EXTRA=00
|
||||
E: SERIO_ID=00
|
||||
E: SERIO_PROTO=00
|
||||
E: SERIO_TYPE=01
|
||||
E: SUBSYSTEM=serio
|
||||
|
||||
P: /devices/platform/i8042/serio4/**input/input6**
|
||||
E: ABS=11000003
|
||||
E: DEVPATH=/devices/platform/i8042/serio4/input/input6
|
||||
--
|
||||
E: NAME="SynPS/2 Synaptics TouchPad"
|
||||
E: PHYS="isa0060/serio4/input0"
|
||||
E: PRODUCT=11/2/7/1b1
|
||||
E: PROP=1
|
||||
E: __SUBSYSTEM=input__
|
||||
E: TAGS=:seat:
|
||||
E: USEC_INITIALIZED=13139
|
||||
|
||||
P: /devices/platform/i8042/serio4/input/input6/**event6 //设备路径path**
|
||||
N: input/event6 **//kernel打印出的设备名称name**
|
||||
__S: input/by-path/platform-i8042-serio-4-event-mouse //设备文件的符号链接symlink__
|
||||
__E: DEVLINKS=/dev/input/by-path/platform-i8042-serio-4-event-mouse //udev导出的环境变量Env__
|
||||
__E: DEVNAME=/dev/input/event6__
|
||||
E: DEVPATH=/devices/platform/i8042/serio4/input/input6/event6
|
||||
E: ID_INPUT=1
|
||||
E: __ID_INPUT_TOUCHPAD=1__
|
||||
E: __ID_PATH=platform-i8042-serio-4__
|
||||
E: ID_PATH_TAG=platform-i8042-serio-4
|
||||
E: ID_SERIAL=noserial
|
||||
E: MAJOR=13
|
||||
E: MINOR=70
|
||||
E: SUBSYSTEM=input
|
||||
E: USEC_INITIALIZED=13541
|
||||
|
||||
P: /devices/platform/i8042/serio4/input/input6/mouse0
|
||||
N: input/mouse0
|
||||
S: input/by-path/platform-i8042-serio-4-mouse
|
||||
E: DEVLINKS=/dev/input/by-path/platform-i8042-serio-4-mouse
|
||||
E: DEVNAME=/dev/input/mouse0
|
||||
E: DEVPATH=/devices/platform/i8042/serio4/input/input6/mouse0
|
||||
E: ID_INPUT=1
|
||||
E: ID_INPUT_TOUCHPAD=1
|
||||
E: ID_PATH=platform-i8042-serio-4
|
||||
E: ID_PATH_TAG=platform-i8042-serio-4
|
||||
E: ID_SERIAL=noserial
|
||||
E: MAJOR=13
|
||||
E: MINOR=32
|
||||
E: SUBSYSTEM=input
|
||||
E: USEC_INITIALIZED=13486
|
||||
|
||||
===== X =====
|
||||
X has __a udev config backend__ which queries udev for the various input devices. It does this at startup and also watches for hotplugged devices. X looks at the different **ID_INPUT_*** properties to determine whether it’s a keyboard, a mouse, a touchpad, a joystick, or some other device. This information can be used in **/etc/X11/xorg.conf.d** files in the form of MatchIsPointer, MatchIsTouchpad, MatchIsJoystick, etc. in __InputClass__ sections to see whether to apply configuration to a given device.
|
||||
|
||||
Xorg has a handful of its own drivers to handle input devices, including **evdev, synaptics, and joystick**. And here is where things start to get confusing.
|
||||
|
||||
Linux has this great __generic event interface in evdev__, which means that very few drivers are needed to interact with hardware, since they’re not speaking device-specific protocols. Of the few needed on Linux nearly all of them speak evdev, including the three I listed above.
|
||||
|
||||
evdev即事件驱动程序,为输入子系统提供了一个默认的事件处理方法。它接收来自硬件底层驱动程序的大多数事件,并使用相应的逻辑对其进行处理。evdev输入事件驱动
|
||||
程序从底层驱动程序接收事件信息,将其反映到sysfs文件系统中,用户程序通过对sysfs文件系统的操作,就能够达到处理事件的目的。
|
||||
|
||||
The evdev driver provides basic __keyboard and mouse__ functionality, speaking — obviously — evdev through the **/dev/input/eventN** devices. It also handles things like the **lid(linux input device) and power switches**. This is the basic, generic input driver for Xorg on Linux.
|
||||
|
||||
The synaptics driver is the most confusing of all. It also speaks evdev to the kernel. On Linux it does not talk to the hardware directly, and is __in no way Synaptics™ hardware-specific__. The synaptics driver is simply a separate driver from evdev which adds a lot of features expected of touchpad hardware, for example two-finger scrolling. It should probably be renamed the “touchpad” module, except that on non-Linux OSes it can still speak the Synaptics protocol.
|
||||
|
||||
The joystick driver similarly handles joysticky things, but speaks evdev to the kernel rather than some device-specific protocol.
|
||||
|
||||
synaptics和joystick驱动程序其实都不是直接控制硬件的驱动,相反,它们从硬件驱动程序接收事件,然后进行处理,将结果通过evdev协议发给kernel。
|
||||
|
||||
X only has concepts of __keyboards and pointers, the latter of which includes mice, touchpads, joysticks, wacom tablets, etc__.
|
||||
|
||||
X also has the concept of the __core keyboard and pointer__, which is how events are most often delivered to applications. By default all devices send core events, but certain setups might want to make devices non-core.
|
||||
|
||||
If you want to receive events for non-core devices, you need to use the **XInput or XInput2 extensions** for that. XInput exposes core-like events (like DeviceMotionNotify and DeviceButtonPress), so it is not a major difficulty to use, although its setup is annoyingly different than most other X extensions. I have not used XInput2.
|
||||
|
||||
Peter Hutterer’s blog is an excellent resource for all things input related in X.
|
||||
40
Zim/观点/一些有趣的编程名言.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-11-30T20:20:03+08:00
|
||||
|
||||
====== 一些有趣的编程名言 ======
|
||||
Created Friday 30 November 2012
|
||||
原文:http://ihower.tw/blog/archives/7046/
|
||||
|
||||
以下内容收集自一些优秀的技术书籍章节开头的名言佳句,非常有意思,直接或间接反映了软件开发中的一些事情。
|
||||
|
||||
生命太短暂,不要去做一些根本__没有人想要__的东西。——Ash Maurya,Running Lean 作者
|
||||
如果你交给某人一个程序,你将折磨他一整天;如果你教某人如何编写程序,你将折磨他一辈子。——David Leinweber
|
||||
软件设计有两种方式:一种方式是,使软件过于简单,明显没有缺陷;另一种方式是,使软件过于复杂,没有明显的缺陷。——C.A.R. Hoare
|
||||
其实,我尝试着使Ruby更自然,而不是简单。Ruby看起来很简单,但内部是非常复杂的,就像我们的身体一样。——松本行弘,Ruby之父
|
||||
大部分情况下,**构建程序的过程本质上是对规范调试的过程**。——Fred Brooks,《人月神话》作者
|
||||
软件开发往往是这样:最开始的90%代码占用了开始的90%的开发时间;剩下10%代码同样需要90%的开发时间。——Tom Cargill
|
||||
当你试图解决一个__你不理解的问题__时,复杂化就产成了。——Andy Boothe
|
||||
用几个小时来制定计划,可以节省几周的编程时间。—— 匿名
|
||||
__控制复杂性__是计算机编程的本质。—— Brian Kernighan
|
||||
计算机科学领域的所有问题都可以通过其他方式间接解决。——David Wheeler
|
||||
编程是两队人马在竞争:软件工程师努力设计出最大最好的连白痴都会使用的程序;而宇宙在拼命制造最大最好的白痴。到目前为止,宇宙是胜利者。—— Rick Cook
|
||||
调试一个初次见到的代码比重写代码要困难两倍。因此,按照定义,如果你写代码非常巧妙,那么没有人足够聪明来调试它。—— Brian W. Kernighan
|
||||
我不是一个伟大的程序员,我只是一个具有__良好习惯的优秀程序员__。― Kent Beck
|
||||
你们中大多数人都熟悉程序员的美德,有三种:那就是懒惰、急躁和傲慢。– Larry Wall,Perl語言发明人
|
||||
任何一个傻瓜都会写能够让机器理解的代码,只有好的程序员才能写出人类可以理解的代码。——Martin Fowler
|
||||
靠代码行数来衡量开发进度,就像是凭重量来衡量飞机制造的进度。——比尔•盖茨
|
||||
这不是一个bug,这只是一个未列出来的特性。——匿名
|
||||
作为一个程序员,郁闷的事情是,面对一个代码块,却不敢去修改。更糟糕的是,这个代码块还是自己写的。—— Peyton Jones
|
||||
它在我的机器上可以很好运行!——大部分程序员
|
||||
**能说算不上什么,有本事就把你的代码给我看看。**——Linus Torvalds,Linux之父
|
||||
我认为对象就像是生物学里的细胞,或者网络中的一台计算机,只能够通过消息来通信——Alan Kay,Smalltalk的发明人,面向对象之父
|
||||
当你选择了一种语言,意味着你还选择了__一组技术、一个社区__。——Joshua Bloch
|
||||
质量、速度、廉价,选择其中两个。——匿名
|
||||
过早的优化是罪恶之源。——Donald Knuth
|
||||
没有什么代码的执行速度比空代码更快。——Merb核心原则
|
||||
如果你是房间里最聪明的人,那么你走错房间了。——匿名
|
||||
如果只需更改一个单一的代码行,你的部门需要花费多长时间?——Mary Poppendieck
|
||||
九个人不能让一个孩子在一个月内出生。——Fred Brooks,《人月神话》作者
|
||||
好代码本身就是最好的文档。当你需要添加一个注释时,你应该考虑如何修改代码才能不需要注释。——Steve McConnell,Code Complete 作者
|
||||
一个人在教会电脑之前,别说他真正理解这个东西了。——Donald Knuth
|
||||