⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix编程应用问答中文版.txt

📁 这份文档不是FAQ(Frequently Answered Question)
💻 TXT
📖 第 1 页 / 共 5 页
字号:
这里的超时设置针对登录过程,而不是登录成功后的shell会话超时设置。

1.6 一个目录拥有setgid设置,怎么理解

Q: 对一个目录做了setgid设置,可我并没有发现这和正常情况有什么区别

A: John Riddoch <jr@scms.rgu.ac.uk>

在这种目录下创建新文件时将采用setgid设置对应的属组,比如

$ ls -ld b
drwxrws---   2 jr       group     512 Mar 14 17:13 b/
$ touch b/a
$ ls -l b/a
-rw-------   1 jr       group       0 Mar 14 17:13 b/a
$ id
uid=178(jr) gid=10(staff)

jr的缺省组是staff,而现在b/a文件属组是group。

D: 小四 <scz@nsfocus.com>

SPARC/Solaris 7下测试

如果目录拥有SGID设置,那么该目录下新创建的文件将继承该目录的属组,而不是创
建者所对应的GID。

[root@ /export/home/scz]> id
uid=0(root) gid=1(other)  <-- 注意当前用户的属组
[root@ /export/home/scz]> mkdir groupsgid
[root@ /export/home/scz]> ls -ld groupsgid
drwxr-xr-x root other groupsgid/
[root@ /export/home/scz]> chown scz:users groupsgid
[root@ /export/home/scz]> chmod g+s groupsgid
[root@ /export/home/scz]> ls -ld groupsgid
drwxr-sr-x scz users groupsgid/  <-- 目录拥有SGID设置
[root@ /export/home/scz]> cd groupsgid/
[root@ /export/home/scz/groupsgid]> touch scz_0
[root@ /export/home/scz/groupsgid]> ls -l scz_0
-rw-r--r-- root users scz_0  <-- 注意属组变化
[root@ /export/home/scz/groupsgid]> chmod g-s ../groupsgid/
[root@ /export/home/scz/groupsgid]> ls -ld ../groupsgid/
drwxr-xr-x scz users ../groupsgid/
[root@ /export/home/scz/groupsgid]> touch scz_1
[root@ /export/home/scz/groupsgid]> ls -l scz_1
-rw-r--r-- root other scz_1  <-- 注意属组变化
[root@ /export/home/scz/groupsgid]>

1.7 非Sun Console上有无等价Stop-A的按键

A: neomilev

如果是便携机,尝试alt/break 或者 ctrl/break。如果是vt100终端,尝试F11 或者
break

1.8 如何让一个用户只能ftp而无法telnet

A: 小四 <scz@nsfocus.com>

修改该用户在/etc/passwd中的shell为/bin/false,在/etc/shells文件中增加
/bin/false,此时,该用户只能ftp,telnet失败。

如果/bin/false不灵,干脆换成/bin/nonexist即可。其实/bin/false不灵只是暂时
某些缓冲机制的结果,重启后必然有效,不重启的话可能要等待一定时间之后才见效
果。

如果将/bin/false换成/usr/bin/passwd,则用户可以远程telnet修改自己的口令,
也可以ftp登录,但无法远程telnet登录获取shell。

1.9 Solaris 8上tftpd的使用

A: Solaris 8上in.tftpd(1M)手册页

--------------------------------------------------------------------------
维护命令                                                      in.tftpd(1M)

名字

    in.tftpd, tftpd - Internet Trivial File Transfer Protocol Server

摘要

    in.tftpd [ -s ] [ homedir ]

抽述

    tftpd通常通过inetd.conf启动,缺省是注释掉的,需要手工开放。

    在响应请求之前,tftpd试图切换自身的当前目录到指定的"homedir",缺省设置
    是/tftpboot。

    tftp不要求帐号、口令即可访问远程系统。由于缺乏身份认证信息,in.ftpd在
    处理get请求时只允许访问全局可读文件。而在处理put请求时,要求server端文
    件名已存在且全局可写。

    in.tftpd以nobody身份运行。

选项

    -s 指定该选项时,tftpd切换自身当前目录到指定"homedir"必须成功,同时
       tftpd会以"homedir"为根做chroot操作。

文件

    /etc/inetd.conf
--------------------------------------------------------------------------

tftpd在处理请求失败时会写/var/adm/messages,可用如下命令查看错误信息

# tail -5 /var/adm/messages

tftpd侦听69/udp口。

1.10 为什么Sun工作站非要输入boot命令才能启动

Q: 我有台Sun工作站,每次开机后停在ok状态下,需要手工输入boot命令才能启动,
   现在想避免这种效果,怎么办

A: /usr/sbin/eeprom auto-boot?=true
   /usr/sbin/eeprom auto-boot?  <-- 查询

A: dengdai@SMTH

进入OBP状态

ok setenv auto-boot? true
ok setenv boot-device disk

反之

ok setenv auto-boot? false

1.11 如何让Solaris识别新增加的硬件

Q: 比如新增加了网卡、硬盘、光驱什么的,如何让Solaris意识到这种增加

A: spp(低音炮) & suxm <suxm@gnuchina.org>

有三种办法

a. Stop-A进入OBP状态,输入boot -r
b. sync(重复);reboot -- -r
c. touch /reconfigure;sync(重复);reboot

参看reboot(1M)、boot(1M)、eeprom(1M)、kernel(1M)、cfgadm(1M)、psradm(1M)手
册页

Q: 我新增加了一块硬盘,不想boot -r而立即生效,怎么办

A: 老大 <willxu@public.cs.hn.cn> 2001-12-04 16:51

直接将第二块硬盘接上去,然后顺序执行如下命令,不用重新启动机器

modunload -i 0
drvconfig(1M)
devlinks(1M)
disks(1M)

如果需要重新格式化、分区、创建文件系统,就继续执行

format(1M)
newfs(1M)

1.12 Solaris 9如何在命令行上增加新用户

A:

useradd -u <uid> -g other -d /export/home/<your> -s /usr/bin/bash -c <your> -m <your>

2. 堆栈相关问题

2.0 理解SIGBUS与SIGSEGV

Q: SIGSEGV我能理解,但有时碰上SIGBUS,这该如何理解。

A: nkwht@smth

nkwht用Google获取这样一些知识。有多种可能导致SIGBUS信号:

1) 硬件故障,不用说,程序员最常碰上的肯定不是这种情形。

2) Linux平台上执行malloc(),如果没有足够的RAM,Linux不是让malloc()失败返回,
   而是向当前进程分发SIGBUS信号。

   注: 对该点执怀疑态度,有机会可自行测试确认当前系统反应。

3) 某些架构上访问数据时有对齐的要求,比如只能从4字节边界上读取一个4字节的
   数据类型。IA-32架构没有硬性要求对齐,尽管未对齐的访问降低执行效率。另外
   一些架构,比如SPARC、m68k,要求对齐访问,否则向当前进程分发SIGBUS信号。

SIGBUS与SIGSEGV信号一样,可以正常捕获。SIGBUS的缺省行为是终止当前进程并产
生core dump。

A: Marc Rochkind <rochkind@basepath.com>

SIGBUS与SIGSEGV信号的一般区别如下:

1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该
   指针。通常是未对齐的数据访问所致。

2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对
   应该地址。

A: scz <scz@nsfocus.com> 2002-11-20

参"2.4 如何编程获取栈底地址"中如何捕获SIGBUS与SIGSEGV信号,并利用sigsetjmp、
siglongjmp重获控制权。

测试表明,在x86/Linux、x86/Solaris、SPARC/Solaris平台上,越过栈底的地址访
问导致SIGSEGV信号。在x86/FreeBSD、x86/NetBSD、x86/OpenBSD平台上,越过栈底
的地址访问导致SIGBUS信号,而不是SIGSEGV信号。

下面举例解释一下,什么叫未对齐的数据访问。

--------------------------------------------------------------------------
/*
 * Test: SPARC/Solaris 8 64-bit kernel mode
 * gcc -Wall -pipe -g -o bus bus.c
 */
#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char * argv[] )
{
    unsigned int        i = 0x12345678;
    unsigned short int *q = NULL;
    unsigned char      *p = ( unsigned char * )&i;

    *p = 0x00;
    q  = ( unsigned short int * )( p + 1 );
    *q = 0x0000;
    return( EXIT_SUCCESS );
}  /* end of main */
--------------------------------------------------------------------------

$ ./bus
总线错误 (core dumped)
$ gdb ./bus core
GNU gdb 5.0
#0  0x1084c in main (argc=1, argv=0xffbefc54) at bus.c:16
16          *q = 0x0000;
(gdb) disas main
Dump of assembler code for function main:
0x10810 <main>   :      save  %sp, -128, %sp
0x10814 <main+4> :      st  %i0, [ %fp + 0x44 ]
0x10818 <main+8> :      st  %i1, [ %fp + 0x48 ]
0x1081c <main+12>:      sethi  %hi(0x12345400), %o1
0x10820 <main+16>:      or  %o1, 0x278, %o0     ! 0x12345678
0x10824 <main+20>:      st  %o0, [ %fp + -20 ]
0x10828 <main+24>:      clr  [ %fp + -24 ]
0x1082c <main+28>:      add  %fp, -20, %o0
0x10830 <main+32>:      st  %o0, [ %fp + -28 ]
0x10834 <main+36>:      ld  [ %fp + -28 ], %o0
0x10838 <main+40>:      clrb  [ %o0 ]
0x1083c <main+44>:      ld  [ %fp + -28 ], %o0
0x10840 <main+48>:      add  %o0, 1, %o1
0x10844 <main+52>:      st  %o1, [ %fp + -24 ]
0x10848 <main+56>:      ld  [ %fp + -24 ], %o0
0x1084c <main+60>:      clrh  [ %o0 ]
0x10850 <main+64>:      clr  %i0
0x10854 <main+68>:      b  0x1085c <main+76>
0x10858 <main+72>:      nop
0x1085c <main+76>:      ret
0x10860 <main+80>:      restore
End of assembler dump.
(gdb) i r pc
pc             0x1084c  67660
(gdb) i r o0
o0             0xffbefbdd       -4260899
(gdb) x/3bx 0xffbefbdd
0xffbefbdd:     0x34    0x56    0x78
(gdb)

从C语言来说,执行"*q = 0x0000;"时导致SIGBUS了。从汇编指令来说,执行"clrh [%o0]"
时导致SIGBUS了,寄存器%o0值为0xffbefbdd,这个地址未对齐在双字节边界上。

注意,gcc编译时并未指定-O<n>进行优化,但仍然使用clrh,而不是两次clrb。类似
的汇编指令有ldw、lduh等等。有人可能碰上读操作也导致SIGBUS,觉得不可理解,
其实读写导致SIGBUS没有本质区别,比如ldw只能读4字节边界上的地址。

bus.c是显式的未对齐。程序员实际最容易面对的是隐式未对齐,主要来自指针的强
制类型转换。下面举例说明这种情形。

--------------------------------------------------------------------------
/*
 * Test: SPARC/Solaris 8 64-bit kernel mode
 * gcc -Wall -pipe -g -o other_bus other_bus.c
 */
#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char * argv[] )
{
    unsigned int        i = 0x12345678;
    unsigned short int  j = 0x0000;

    j = *( ( unsigned short int * )( ( ( unsigned char * )&i  ) + 1 ) );
    return( EXIT_SUCCESS );
}  /* end of main */
--------------------------------------------------------------------------

$ ./other_bus
总线错误 (core dumped)
$ gdb ./other_bus core
GNU gdb 5.0
#0  main (argc=1, argv=0xffbefc44) at other_bus.c:13
13          j = *( ( unsigned short int * )( ( ( unsigned char * )&i  ) + 1 ) );
(gdb) disas main
Dump of assembler code for function main:
0x10810 <main>   :      save  %sp, -120, %sp
0x10814 <main+4> :      st  %i0, [ %fp + 0x44 ]
0x10818 <main+8> :      st  %i1, [ %fp + 0x48 ]
0x1081c <main+12>:      sethi  %hi(0x12345400), %o1
0x10820 <main+16>:      or  %o1, 0x278, %o0     ! 0x12345678
0x10824 <main+20>:      st  %o0, [ %fp + -20 ]
0x10828 <main+24>:      clrh  [ %fp + -22 ]
0x1082c <main+28>:      lduh  [ %fp + -19 ], %o0
0x10830 <main+32>:      sth  %o0, [ %fp + -22 ]
0x10834 <main+36>:      clr  %i0
0x10838 <main+40>:      b  0x10840 <main+48>
0x1083c <main+44>:      nop
0x10840 <main+48>:      ret
0x10844 <main+52>:      restore
End of assembler dump.
(gdb) i r pc
pc             0x1082c  67628
(gdb)

因此在SPARC架构上编程,一定要留神强制类型转换,务必清楚自己正在干什么,有
没有隐患。

2.1 如何理解pstack的输出信息

Q: 080603a7 main    (1, 80479b8, 80479c0)  + d53
   结尾的d53是什么

A: Roger A. Faulkner <raf@sunraf.Sun.COM>

在代码段绝对地址0x080603a7处,main()调用了一个函数,0x080603a7正是
main + 0xd53,换句话说,从main()函数开始的0xd53偏移处。

2.3 Solaris中如何获取一个C程序的调用栈回溯

Q: 我想在Solaris 2.6及其后续版本上获取一个C程序的调用栈回溯,类似如下输出

   (10)  0x00045e08  integ + 0x408    [./two_brn.e]
   (11)  0x0006468c  trajcem + 0x128  [./two_brn.e]
   (12)  0x00055490  fly_traj + 0xf58 [./two_brn.e]
   (13)  0x0004052c  top_level + 0x14 [./two_brn.e]
   (14)  0x000567e4  _start + 0x34    [./two_brn.e]

   这样我就可以知道当程序崩溃、死锁的时候代码执行到了何处。在HP-UX和IRIX上
   可以利用U_STACK_TRACE()和trace_back_stack_and_print(),Solaris上呢?

Q: 有没有办法显示当前堆栈中的数据(GNU/Linux系统)?我希望自己的异常处理程序
   在进程结束前dump整个栈区(stack),以便观察到栈顶是什么函数。对于调试意想
   不到的运行时错误而言,这很重要。

Q: Is it possible to unwind the stack on Solaris 8? Is there an API that I
   could use? I know that with TRU64(Digital UNIX) there are the exception
   handling routines: except_virtual_unwind() and except_capture_context().
   Basically, what I am trying to do is print out the stack on demand,
   just as dbx or gdb would.

A: Bjorn Reese <breese@mail1.stofanet.dk>

   用/usr/proc/bin/pstack [-F] <pid ...>

   参看这个例子代码,http://home1.stofanet.dk/breese/debug/debug.tar.gz

Q: is there a way to access call stack information at run time from within
   a program?  i've been maintaining my own crude stack using __FUNCTION__
   and linked lists but can't help but think there's gotta be a better
   way...

A: Nate Eldredge <neldredge@hmc.edu>

   这依赖于你的系统,如果使用glibc 2.1或更新版本,可以使用backtrace()函数,
   参看<execinfo.h>,其他系统可能有不同的技术支持。

   注意,你所使用的办法可能是唯一能够保证跨平台使用的

A: Andrew Gabriel <andrew@cucumber.demon.co.uk> Consultant Software Engineer

下面是一个backtrace()的应用举例,如果你使用Solaris 2.4及其后续版本,那么这
个例子可以很好的工作。很可能无法工作在64-bit模式下,我没有尝试过,好像
Solaris 7已经提供了一个类似的演示程序。还可以增加某些功能,我没有时间了。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -