who am i和whoami区别

who am i 显示的是实际用户ID即用户登陆的时候的用户ID
whoami   显示的是有效用户ID.
但在大多数情况下,实际用户ID和有效用户ID是一致的。
 
login:zhx
Pssword:
$who am i
zhx     pts/0    2007-08-16   13:16   (:0.0)
$whoami
zhx
当切换用户后:
su
Password:
#who am i
zhx     pts/0   007-08-16   13:16  (:0.0)
#whoami
root
 
也可以说who am i  显示的是切换用户前的实际登陆的用户ID,whoami是切换后的有效的用户ID,此时此终端具有切换后用户的访问权限,如本文中切换后则具有超级用户的访问权限。
 


who am i whoami有何区别?

 

首先要说明uideuideffective user id)的区别。uid就是你login的时候使用的id,而euid则是你当前的有效id。因为登录后我们可以使用su切换用户身份,所以uideuid可能是不同的,程序在运行的时候一般看的都是euid,当然也有特出的,who am i就是一个。

举个例子:用户用ABC登陆,使用su变成root,用who am i看到的是ABC,使用whoami命令看到的是root

login: u1

Password:

$ su

Password:

# /usr/ucb/whoami

root

# who am i

u<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="True" sourcevalue="1" unitname="pts">1<span style="mso-spacerun: yes">         </span>pts</chmetcnv>/4        10 31 23:18   (192.168.0.1)

以下是MMA8452和STM32连接的代码,仅供参考: ```c #include "stm32f10x.h" #include "stdio.h" #define MMA8452_ADDRESS 0x38 #define MMA8452_ID 0x2A #define MMA8452_STATUS 0x00 #define MMA8452_OUT_X_MSB 0x01 #define MMA8452_WHO_AM_I 0x0D #define MMA8452_CTRL_REG1 0x2A #define MMA8452_CTRL_REG1_ACTIVE 0x01 #define I2C_SPEED 100000 #define I2C1_SLAVE_ADDRESS7 0x3F GPIO_InitTypeDef GPIO_InitStructure; void I2C_Configuration(void); void I2C_StartTransmission(I2C_TypeDef* I2Cx, uint8_t transmissionDirection, uint8_t slaveAddress); void I2C_WriteData(I2C_TypeDef* I2Cx, uint8_t data); void I2C_StopTransmission(I2C_TypeDef* I2Cx); uint8_t I2C_ReadAck(I2C_TypeDef* I2Cx); uint8_t I2C_ReadNack(I2C_TypeDef* I2Cx); int main(void) { uint8_t tempData[6]; uint8_t whoAmI; I2C_Configuration(); I2C_StartTransmission(I2C1, I2C_Direction_Transmitter, MMA8452_ADDRESS); I2C_WriteData(I2C1, MMA8452_WHO_AM_I); I2C_StopTransmission(I2C1); I2C_StartTransmission(I2C1, I2C_Direction_Receiver, MMA8452_ADDRESS); whoAmI = I2C_ReadNack(I2C1); I2C_StopTransmission(I2C1); if (whoAmI != MMA8452_ID) { printf("Error: Could not communicate with MMA8452.\n"); while (1) {} } GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); I2C_StartTransmission(I2C1, I2C_Direction_Transmitter, MMA8452_ADDRESS); I2C_WriteData(I2C1, MMA8452_CTRL_REG1); I2C_WriteData(I2C1, MMA8452_CTRL_REG1_ACTIVE); I2C_StopTransmission(I2C1); while (1) { I2C_StartTransmission(I2C1, I2C_Direction_Transmitter, MMA8452_ADDRESS); I2C_WriteData(I2C1, MMA8452_OUT_X_MSB); I2C_StopTransmission(I2C1); I2C_StartTransmission(I2C1, I2C_Direction_Receiver, MMA8452_ADDRESS); tempData[0] = I2C_ReadAck(I2C1); tempData[1] = I2C_ReadAck(I2C1); tempData[2] = I2C_ReadAck(I2C1); tempData[3] = I2C_ReadAck(I2C1); tempData[4] = I2C_ReadAck(I2C1); tempData[5] = I2C_ReadNack(I2C1); I2C_StopTransmission(I2C1); int16_t xData = ((tempData[0] << 8) | tempData[1]) >> 2; int16_t yData = ((tempData[2] << 8) | tempData[3]) >> 2; int16_t zData = ((tempData[4] << 8) | tempData[5]) >> 2; printf("X: %d, Y: %d, Z: %d\n", xData, yData, zData); if (xData > 1000) { GPIO_SetBits(GPIOC, GPIO_Pin_13); } else { GPIO_ResetBits(GPIOC, GPIO_Pin_13); } } } void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); } void I2C_StartTransmission(I2C_TypeDef* I2Cx, uint8_t transmissionDirection, uint8_t slaveAddress) { while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2Cx, slaveAddress, transmissionDirection); if (transmissionDirection == I2C_Direction_Transmitter) { while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); } if (transmissionDirection == I2C_Direction_Receiver) { while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); } } void I2C_WriteData(I2C_TypeDef* I2Cx, uint8_t data) { I2C_SendData(I2Cx, data); while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } void I2C_StopTransmission(I2C_TypeDef* I2Cx) { I2C_GenerateSTOP(I2Cx, ENABLE); } uint8_t I2C_ReadAck(I2C_TypeDef* I2Cx) { I2C_AcknowledgeConfig(I2Cx, ENABLE); while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); return I2C_ReceiveData(I2Cx); } uint8_t I2C_ReadNack(I2C_TypeDef* I2Cx) { I2C_AcknowledgeConfig(I2Cx, DISABLE); while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); return I2C_ReceiveData(I2Cx); } ``` 该代码使用STM32的I2C接口与MMA8452进行通信。在主循环中,它从MMA8452读取加速度数据,并根据X轴的值控制PC13引脚的状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值