So Tired !_! 逆水行舟, 不进则退!

28May/18

amixer命令用于设置系统音量

Posted by Nick Xu

 amixer命令用于设置系统音量

   该句为-c选择0的声卡(貌似),PCM volume设置为增加60*2=120(value值变为加上120),60dB-就是减小60*2=120,如果是如下:

               amixer -c 0 set PCM 60db+

   则为把value设置为60.

  在FX1的case中,value的值如果loopback要过的话,必须得value的值在一定范围80-127以内,不能超过127即爆声(我是这样记的)。

   在FX1的case中,runin阶段有设置系统声卡音量,使音量增大,而这句影响到final阶段的loopback测试,使得播放和录音的两个音频不一样,check_wav时就fail了,但是如果没有amixer命令,不会出错。

使用到命令:

      amixer controls(找到一个关于PCM的控制项PCM Playback Volume)

      amixer cget numid=1,iface=MAXER,name=‘PCM Playback Volume’(出现PCM的value的数据)

      amixer -c 0 set PCM 60dB+(将value值在原基础上加上60*2=120)

 Q:但是FX1中有一些批次产品是reboot之后会恢复default 的value值,有一些则不会。

amixer命令:

  alsamixer是Linux 音频架构ALSA中的Alsa工具的其中一个,用于配置音频的各个参数。

  alsamixer是基于文本下的图形界面的,可以通过键盘的上下键,左右键等,很方便地设置需要的音量,开关某个switch(开关)等等操作。

  amixer,是alsamixer的文本模式,即命令行模式,需要用amixer命令的形式去配置你的声卡的各个选项。

对于amixer的使用,你首先需要搞懂你要设置的参数是哪些,然后才可能去了解,如何去配置对应的值,整体来说,相对alsamixer来说,是有点繁琐,下面简要介绍其具体用法:

  1.先看看amixer支持哪些命令,大概有哪些功能

 # amixer --help

  Usage: amixer [command]

  Available options:
  -h,--help       this help
 -c,--card N     select the card
 -D,--device N   select the device, default 'default'
 -d,--debug      debug mode
 -n,--nocheck    do not perform range checking
 -v,--version    print version of this program
 -q,--quiet      be quiet
 -i,--inactive   show also inactive controls
 -a,--abstract L select abstraction level (none or basic)
 -s,--stdin      Read and execute commands from stdin sequentially

   Available commands:
    scontrols       show all mixer simple controls
   scontents       show contents of all mixer simple controls (default command)
   sset sID P      set contents for one mixer simple control
   sget sID        get contents for one mixer simple control
   controls        show all controls for given card
   contents        show contents of all controls for given card
   cset cID P      set control contents for one control
   cget cID        get control contents for one control

2.再看看当前你的音频系统(不同的音频驱动对应不同的内容和操作接口)提供了那些供你使用的接口去操作

关于驱动里面已经提供了多少接口可以去操作,可以用命令:

amixer contents

查看,比如:

amixer controls
numid=3,iface=MIXER,name='Master Mode Switch'
numid=29,iface=MIXER,name='Master Mux'
numid=4,iface=MIXER,name='Master Quality Switch'
numid=2,iface=MIXER,name='Master Switch'
numid=1,iface=MIXER,name='Master Volume'
numid=7,iface=MIXER,name='PCM Mode Switch'
numid=6,iface=MIXER,name='PCM Switch'
numid=5,iface=MIXER,name='PCM Volume'
numid=21,iface=MIXER,name='Line Input Switch'
numid=16,iface=MIXER,name='Line Mode Switch'
numid=27,iface=MIXER,name='Line Mux'
。。。。。
numid=9,iface=MIXER,name='Mic Switch'
numid=8,iface=MIXER,name='Mic Volume'
numid=19,iface=MIXER,name='ADC Mode Switch'
numid=28,iface=MIXER,name='ADC Mux'
。。。。。。。。
去查看,当然你的Linux内核支持哪些配置参数,如上,一共有20多个参数可供你配置。

而对于所有的当然的配置的值,可以通过这个查看:

amixer contents
numid=3,iface=MIXER,name='Master Mode Switch'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'Common Buffer Off'
; Item #1 'Common Buffer On'
: values=0
。。。。。。。。。。

numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=27,27
| dBscale-min=-40.50dB,step=1.50dB,mute=0
numid=24,iface=MIXER,name='Mixer ADC Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=off
numid=26,iface=MIXER,name='Mixer DAC Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=25,iface=MIXER,name='Mixer Line Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=23,iface=MIXER,name='Mixer Mic Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on

3.搞懂如何去设置某个参数

总结起来就是,先要用get系列命令去看懂有哪些接口,然后再去用set系列的命令,去设置对应你所要设置的值。

想要针对某项设置,比如想要设置上面的的主音量,master volume,即controls中显示的:

numid=5,iface=MIXER,name='PCM Volume'
那么,可以先看看当前的值:

amixer cget numid=5,iface=MIXER,name='PCM Volume'
numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=27,27
| dBscale-min=-40.50dB,step=1.50dB,mute=0

显示的是最大的27,假设想要设置为25,那么就用cset去设置:

amixer cset numid=5,iface=MIXER,name='PCM Volume' 25
numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=25,25
| dBscale-min=-40.50dB,step=1.50dB,mute=0

再比如,去将'Mic Supply 的switch关闭:

amixer cset numid=12,iface=MIXER,name='Mic Supply Switch' Off
numid=12,iface=MIXER,name='Mic Supply Switch'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'On'
; Item #1 'Off'
: values=1

总结一下用法,就是:

amixer cget    controls中所输出的某个参数

amixer cset    controls中所输出的某个参数      具体的值(比如,0,1,On,Off等)

【提示】

同上面介绍的的cget/cset系列命令:

controls        show all controls for given card
contents        show contents of all controls for given card
cset cID P      set control contents for one control
cget cID        get control contents for one control

类似的,还有另外一套sget/sset系列的命令:

scontrols       show all mixer simple controls
scontents       show contents of all mixer simple controls (default command)
sset sID P      set contents for one mixer simple control
sget sID        get contents for one mixer simple control

也是同样做法,比如:

通过查看当然有哪些选择可以控制:

amixer scontrols
Simple mixer control 'Master',0
Simple mixer control 'Master Mode',0
Simple mixer control 'Master Mux',0
Simple mixer control 'Master Quality',0
。。。

同理,amixer scontents,可以查看当前所有的值,具体就不在这列举了。

另外,去查看或者配置用sget,比如:

amixer sget 'Microphone Input',0
Simple mixer control 'Microphone Input',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [off]

如果想要修改对应设置,用amixer sset ,具体用法是:

amixer sset sID(控制字符串) P(支持的某个值)

其中sID,就是上面的Simple mixer control后面的那个字符串,比如'Master Mux',0

而对其设置就是,先看看其提供了哪些供你设置的值:

amixer sget 'Master Mux',0
Simple mixer control 'Master Mux',0
Capabilities: enum
Items: 'Sum' 'DAC' 'Line' 'Mic'
Item0: 'DAC'

然后比如要设置成Line的,就可以这样:

amixer sset 'Master Mux',0 Line
Simple mixer control 'Master Mux',0
Capabilities: enum
Items: 'Sum' 'DAC' 'Line' 'Mic'
Item0: 'Line'

 

28May/18

记ekho安装到嵌入式设备

Posted by Nick Xu

ekho按照官方编译安装ubuntu版本的

编译后运行发现报错

pa_simple_new() failed: Access denied

pa_sample_spec(format=3,rate=16000,channels=ch=1)

Fail to init audio stream.

Fail to init sound.

最后发现是 pulseaudio 服务里用了--system参数, 去掉即可正常使用, 具体原因还不清楚.

9Mar/18

ubuntu在shell下连接蓝牙键盘

Posted by Nick Xu

k380键盘

安装bluez

1
2
3
4
5
6
7
8
9
10
11
12
13
bluetoothctl
 
devices
 
power on
 
scan on
 
pair macaddress
 
trust macaddress
 
connect macaddress

 

https://www.youtube.com/watch?v=fBqOSENDakY

Filed under: Linux Comments Off
28Feb/18

一步步教你创建自己的数字货币(代币)进行ICO

Posted by Nick Xu

本文从技术角度详细介绍如何基于以太坊ERC20创建代币的流程.

写在前面

本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊、智能合约有所了解,如果你还不了解,建议你先看以太坊是什么

代币Token

如果不那么追求精确的定义,代币就是数字货币,比特币、以太币就是一个代币。 利用以太坊的智能合约可以轻松编写出属于自己的代币,代币可以代表任何可以交易的东西,如:积分、财产、证书等等。 因此不管是出于商业,还是学习很多人想创建一个自己的代币,先贴一个图看看创建的代币是什么样子。

今天我们就来详细讲一讲怎样创建一个这样的代币。

ERC20 Token

也许你经常看到ERC20和代币一同出现, ERC20是以太坊定义的一个代币标准。 要求我们在实现代币的时候必须要遵守的协议,如指定代币名称、总量、实现代币交易函数等,只有支持了协议才能被以太坊钱包支持。 其接口如下:

contract ERC20Interface {

    string public constant name = "Token Name";
    string public constant symbol = "SYM";
    uint8 public constant decimals = 18;  // 18 is the most common number of decimal places

    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

简单说明一下: name : 代币名称 symbol: 代币符号 decimals: 代币小数点位数,代币的最小单位, 18表示我们可以拥有 .0000000000000000001单位个代币。 totalSupply() : 发行代币总量。 balanceOf(): 查看对应账号的代币余额。 transfer(): 实现代币交易,用于给用户发送代币(从我们的账户里)。 transferFrom(): 实现代币用户之间的交易。 allowance(): 控制代币的交易,如可交易账号及资产。 approve(): 允许用户可花费的代币数。

编写代币合约代码

代币合约代码:

pragma solidity ^0.4.16;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }

contract TokenERC20 {
    string public name;
    string public symbol;
    uint8 public decimals = 18;  // 18 是建议的默认值
    uint256 public totalSupply;

    mapping (address => uint256) public balanceOf;  // 
    mapping (address => mapping (address => uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Burn(address indexed from, uint256 value);


    function TokenERC20(uint256 initialSupply, string tokenName, string tokenSymbol) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);
        balanceOf[msg.sender] = totalSupply;
        name = tokenName;
        symbol = tokenSymbol;
    }


    function _transfer(address _from, address _to, uint _value) internal {
        require(_to != 0x0);
        require(balanceOf[_from] >= _value);
        require(balanceOf[_to] + _value > balanceOf[_to]);
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }

    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value);
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) public
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }

    function burn(uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value);
        balanceOf[msg.sender] -= _value;
        totalSupply -= _value;
        Burn(msg.sender, _value);
        return true;
    }

    function burnFrom(address _from, uint256 _value) public returns (bool success) {
        require(balanceOf[_from] >= _value);
        require(_value <= allowance[_from][msg.sender]);
        balanceOf[_from] -= _value;
        allowance[_from][msg.sender] -= _value;
        totalSupply -= _value;
        Burn(_from, _value);
        return true;
    }
}

代码的详细解读,请订阅我的小专栏

部署

在开发测试智能合约时,MetaMaskRemix Solidity IDE是两个非常好用的工具,今天就用他们来完成部署。

  1. 安装和配置MetaMask请参考开发、部署第一个去中心化应用,不同的上本文选择了以太坊的测试网络Ropsten,如果你没有余额请点击购买buy,进入的网站可以送一些测试以太币给你,配置好之后,界面应该如下:

  2. 浏览器打开Remix Solidity IDE,复制以上源码粘贴上,在右侧选项参考如图的设置:

    注意Environment和Account和MetaMask保持一致,然后选择合约TokenERC20,填入你想要的发行量,名称及代号,就可以创建合约了。 这时MetaMask会弹出一个交易确认框,点SUBMIT。待合约部署交易确认之后,复制合约地址。

  3. 打开Metamask界面,切换到TOKENS,点添加合约,出现如下对话框:

    填入刚刚复制的地址,点ADD,这时你就可以看到你创建的代币了,如图:

哈哈,你已经完成了代币的创建和部署(正式网络和测试网络部署方法一样),可以在Etherscan查询到我们刚刚部署的代币。可以用它进行ICO了,从此走上人生巅峰(玩笑话,不鼓励大家发行无意义的代币)。

代币交易

由于MetaMask插件没有提供代币交易功能,同时考虑到很多人并没有以太坊钱包或是被以太坊钱包网络同步问题折磨,今天我用网页钱包来讲解代币交易。

  1. 进入网页钱包地址, 第一次进入有一些安全提示需要用户确认。
  2. 进入之后,按照下图进行设置:

  3. 连接上之后,如图

    需要添加代币,填入代币合约地址。

  4. 进行代币转账交易

    在接下来的交易确认也,点击确认即可。

  5. 交易完成后,可以看到MetaMask中代币余额减少了,如图:

代币交易是不是很简单,只要明白了交易流程,使用其他的钱包也是一样的道理。

如果你在创建代币的过程中遇到问题,我的**知识星球**可为大家解答问题。

参考文档

深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

作者:Tiny熊
链接:https://juejin.im/post/5a65d25351882573485a13e3
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Filed under: 其它 Comments Off
7Feb/18

Ubuntu下配置支持Windows访问的samba共享

Posted by Nick Xu

一、安装Ubuntu samba服务器

$ sudo apt-get install samba

$ sudo apt-get install smbclient # Linux客户端测试用

二、创建samba配置文件

1. 备份原配置文件

$ sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

2. 创建共享目录

$ sudo mkdir -p /home/share

一般来说,该目录的权限为755,将其改为777之后,Owner之外的其他用户才有权限写入。

$ sudo chmod 777 /home/share

3. 修改配置文件

$ sudo vim /etc/samba/smb.conf

在smb.conf最后添加:

[share]

path = /home/share

browseable = yes

writable = yes

comment = smb share test

另外,总结一下常见的samba配置及说明:

[share] # 该共享的共享名

comment = smb share test # 该共享的备注

path = /home/share # 共享路径

allow hosts = host(subnet) # 设置该Samba服务器允许的工作组或者域

deny hosts = host(subnet) # 设置该Samba服务器拒绝的工作组或者域

available = yes|no # 设置该共享目录是否可用

browseable = yes|no # 设置该共享目录是否可显示

writable = yes|no # 指定了这个目录缺省是否可写,也可以用readonly = no来设置可写

public = yes|no # 指明该共享资源是否能给游客帐号访问,guest ok = yes其实和public = yes是一样的

user = user, @group # user设置所有可能使用该共享资源的用户,也可以用@group代表group这个组的所有成员,不同的项目之间用空格或者逗号隔开

valid users = user, @group # 指定能够使用该共享资源的用户和组

invalid users = user, @group # 指定不能够使用该共享资源的用户和组

read list = user, @group # 指定只能读取该共享资源的用户和组

write list = user, @group # 指定能读取和写该共享资源的用户和组

admin list = user, @group # 指定能管理该共享资源(包括读写和权限赋予等)的用户和组

hide dot files = yes|no # 指明是否像UNIX那样隐藏以“.”号开头的文件

create mode = 0755 # 指明新建立的文件的属性,一般是0755

directory mode = 0755 # 指明新建立的目录的属性,一般是0755

sync always = yes|no # 指明对该共享资源进行写操作后是否进行同步操作

short preserve case = yes|no # 指明是否区分文件名大小写

preserve case = yes|no # 指明是否保持大小写

case sensitive = yes|no # 指明是否对大小写敏感,一般选no,不然可能引起错误

mangle case = yes|no # 指明混合大小写

default case = upper|lower # 指明缺省的文件名是全部大写还是小写

force user = testuser # 强制把建立文件的属主是谁。如果我有一个目录,让guest可以写,那么guest就可以删除,如果我用force user= testuser强制建立文件的属主是testuser,同时限制create mask = 0755,这样guest就不能删除了

wide links = yes|no # 指明是否允许共享外符号连接,比如共享资源里面有个连接指向非共享资源里面的文件或者目录,如果设置wide links = no将使该连接不可用

max connections = 100 # 设定最大同时连接数

delete readonly = yes|no # 指明能否删除共享资源里面已经被定义为只读的文件

三、创建samba用户

注意,创建samba用户之前,必须先确保有一个同名的Linux用户,否则samba用户会创建失败。

$ sudo smbpasswd -a smbuser

四、重启samba服务

$ sudo service smbd restart

五. 客户端访问测试

1. Linux客户端访问测试

$ smbclient -L //localhost/share

2. Windows客户端访问测试

可以访问如下地址:

\\IP或者主机名\share

如果public = no,此时需要输入samba用户密码;如果public = yes,则作为nobody用户直接访问。

另外,在Windows客户端使用net use * /del /y这条命令可以清理访问缓存。

Filed under: Linux Comments Off
7Feb/18

install tp link wn725n wifi usb adapter on ubuntu

Posted by Nick Xu

I found the solution. I installed the driver for the usb wifi adapter successfully using the following:

sudo apt-get update
sudo apt-get install linux-headers-$(uname -r)
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install git
git clone https://github.com/lwfinger/rtl8188eu
cd rtl8188eu
make all
sudo make install
sudo modprobe 8188eu.ko

and then I used the following command:

sudo lshw -C network

to get the internal wifi driver file name and then add it to blacklist

sudo -H gedit /etc/modprobe.d/blacklist

and add the following line to the end of the file:

blacklist xxxxx

where xxxx is the internal wifi driver file name.

Restart and Ubuntu should now work with the usb adapter.

Note: if your internal wifi is fine then you don't need to blacklist it, i only did that because it was tuened off by hardware switch and doesn't want to turn on again and it turns off the usb wifi as well so i had to blacklist it.

 

 

Actually there are 2 different revision of this tl-wn725n wifi adapter, the v1 and the v2 which have different chipsets.

How to recognize them?

The tp-link website say that is possible to recognize them by the FCCID (labeled on the adapter).

If your FCCID terminates with v2 then is the second revision, which use the RTL8188EUS Realtek chipset.

Otherwise if your FCCID terminates with v1 (or you can't find a hardware version) it is the first revision, based on the Realtek RTL8188CUS chipset.

Where do i find the driver?

For the v2 version on the tp-link website : here

For the v1 version here (from realtek) , or here

More info:

https://wikidevi.com/wiki/TP-LINK_TL-WN725N_v1

 

 

https://help.ubuntu.com/community/HardwareSupportComponentsWirelessNetworkCardsTP-Link#USB

 

[FAILED] ubuntu 16.04 上使用 TP-LINK WN725N 免驱版 无线网卡

该网卡使用MTK 7601u芯片。虽然型号也叫WN725N,但是和之前的WN725N根本就不是一个东西。。。是的,除了生产厂家以及都是黑色USB无线网卡以外,二者没有任何共同点。
插到机器上之后,lsusb显示为:
Bus 003 Device 006: ID 148f:2878 Ralink Technology, Corp.

系统将之挂载为一个cdrom。在Windows上,可以直接使用里面的安装程序进行驱动安装。
并讲网卡模式切换为无线网卡模式。

在Ubuntu上,为了切换模式,参考了usb_modeswitch的data文件:
# RaLink MT7601U
TargetVendor=0x148f
TargetProduct=0x7601
StandardEject=1

是的,只要进行eject即可。。。
可直接执行:
sudo eject /dev/sr0
或者
sudo usb_modeswitch -v 148f -p 2878 -K

之后lsusb,等待一下,即可观察到:
Bus 003 Device 007: ID 148f:7601 Ralink Technology, Corp. MT7601U Wireless Adapter

其实这个等待的时间,是系统正在使用自带mt7601驱动尝试probe网卡。

[  589.049149] usb 3-11: reset high-speed USB device number 7 using xhci_hcd
[  589.179614] mt7601u 3-11:1.0: ASIC revision: 76010001 MAC revision: 76010500
[  589.180380] mt7601u 3-11:1.0: Firmware Version: 0.1.00 Build: 7640 Build time: 201302052146____
[  592.645071] mt7601u 3-11:1.0: Vendor request req:07 off:09a8 failed:-110
[  595.764998] mt7601u 3-11:1.0: Vendor request req:02 off:09a8 failed:-110
[  598.884833] mt7601u 3-11:1.0: Vendor request req:07 off:0734 failed:-110
[  602.004776] mt7601u 3-11:1.0: Vendor request req:42 off:0230 failed:-110
[  605.124673] mt7601u 3-11:1.0: Vendor request req:07 off:0080 failed:-110
[  608.244542] mt7601u 3-11:1.0: Vendor request req:02 off:0080 failed:-110
[  611.364455] mt7601u 3-11:1.0: Vendor request req:02 off:0080 failed:-110
[  611.364489] mt7601u: probe of 3-11:1.0 failed with error -110
[  611.364526] usbcore: registered new interface driver mt7601u

可以看到,probe最终失败了。应该是网卡驱动(分析代码后发现,也可能是firmware)和该型号网卡不匹配。
参照https://askubuntu.com/questions/457061/ralink-mt7601u-148f7601-wi-fi-adapter-installation
手动安装驱动。

sudo apt-get install linux-headers-generic build-essential git

git clone https://github.com/art567/mt7601usta.git

cd mt7601usta/src

make

sudo make install

sudo mkdir -p /etc/Wireless/RT2870STA/

sudo cp RT2870STA.dat /etc/Wireless/RT2870STA/

sudo modprobe mt7601Usta

注意:考虑到之前的驱动已经加载,在执行modprobe之前,应该考虑先将之前的驱动rmmod掉。(实际尝试后发现然并卵。)
系统默认驱动信息:

modinfo mt7601u
filename:       /lib/modules/4.4.0-81-generic/kernel/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko
license:        GPL
firmware:       mt7601u.bin
srcversion:     C4F802D4D12C5BC2BA7FEB7
alias:          usb:v7392p7710d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v2A5Fp1000d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v2955p1001d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v2955p0001d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v2717p4106d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v2001p3D04d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v148Fp760Dd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v148Fp760Cd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v148Fp760Bd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v148Fp760Ad*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v148Fp7601d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v13D3p3434d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v13D3p3431d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0E8Dp760Bd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0E8Dp760Ad*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0B05p17D3d*dc*dsc*dp*ic*isc*ip*in*
depends:        mac80211,cfg80211
intree:         Y
vermagic:       4.4.0-81-generic SMP mod_unload modversions

modprobe执行之后,可以查看sudo lshw -C net
  *-network DISABLED
       description: Wireless interface
       physical id: 2
       logical name: ra0
       capabilities: ethernet physical wireless
       configuration: broadcast=yes driver=RALINK WLAN multicast=yes wireless=Ralink STA
可见系统已经可以识别该网卡,但网络处于disable状态。可能和我机器系统本身有关。在dmesg中可以看到
[ 1108.702033] ModemManager[925]: segfault at 0 ip 0000000000431ab3 sp 00007fffc062e940 error 4 in ModemManager[400000+
103000]
接下来尝试使用ifconfig强行up  ra0
sudo ifconfig ra0 up
命令长时间没有反应

尝试将Ubuntu升级至 17.04,效果依旧。估计要深入分析驱动代码,太浪费时间。同时考虑到未来内核升级也要重新手动修改驱动,用户体验难以接受。决定放弃尝试。

================================================================
最终解决方案:
又购买了普通版本TL-WN725N(更小更便宜),未做任何配置,插在机器上,瞬间完成驱动。
教训:一分钱一分货是不假,但在linux的世界里,性价比才是最安全的标准。

Filed under: Linux Comments Off
17Jan/18

使用cat,awk和sort命令从nginx访问日志中统计user-agent类型

Posted by Nick Xu

业务场景描述如下:

我有一个Nginx的web服务器,需要从统计日志中统计有哪些类型的设备终端和浏览器访问了我的网站。

访问日志中的每条记录是这样的:

使用下面的命令得到user-agent所在的字段

cat cpm.access.log-20141211 | awk -F '"' '{print $6}' > ua_1211.txt

意思是,处理该文件的每一行,指定“为分隔符,只输出第6个文本域

提取的user-agent字段得到的文件为

很显然,需要对这些行进行去重,这只需要一个简单的sort命令就可以请求搞定:

sort ua_1211.txt | uniq -u > ua_1211.sort.txt

对文档按照ascii字符顺序进行排序,同时去掉重复行,并将结果重定向到新文件中

下面是去重后的文件内容

为了结果更精确,我需要对当前目录下面的所有日志都做相同的分析,为此,我需要先将这些文件都合并到一个大日志文件中,再对这个大文件执行上面的操作。使用cat的通配符合并功能很容易实现文件合并:

cat cpm.access.log-2014121* > cpm.access.log

再对这个合并文件cpm.access.log做分析

cat cpm.access.log | awk -F '"' '{print $6}' | sort | uniq -u > ua_analysis.txt

这次我们看到了更多神奇的东西,看来访问各种移动端访问我们网站还是很多的,总结有1333种终端访问。

其实类似的其他场景的问题也可以参照解决。

下面是我收集的user-agent文件,参见下载链接

收集的user-agent大全.txt

观察日志发现UA字符串:

Mozilla/5.0 (compatible; Baiduspider/2.0; http://www.baidu.com/search/spider.html)

参考文献

[1].http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html

[2].http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858385.html

8Jan/18

linux sort 命令详解

Posted by Nick Xu

sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始!

1 sort的工作原理

 

sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear

2 sort的-u选项

它的作用很简单,就是在输出行中去除重复行。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear

pear由于重复被-u选项无情的删除了。

3 sort的-r选项

sort默认的排序方式是升序,如果想改成降序,就加个-r就搞定了。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1

4 sort的-o选项

由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile。

但是,如果你想把排序结果输出到原文件中,用重定向可就不行了。

[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然将number清空了。

就在这个时候,-o选项出现了,它成功的解决了这个问题,让你放心的将结果写入原文件。这或许也是-o比重定向的唯一优势所在。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1

5 sort的-n选项

你有没有遇到过10比2小的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,所以就将10放在2前面喽。这也是sort的一贯作风。

我们如果想改变这种现状,就要使用-n选项,来告诉sort,“要以数值来排序”!

[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19

6 sort的-t选项和-k选项

如果有一个文件的内容是这样:

[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4

这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。

那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?

幸好,sort提供了-t选项,后面可以设定间隔符。(是不是想起了cut和paste的-d选项,共鸣~~)

指定了间隔符之后,就可以用-k来指定列数了。

[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3

我们使用冒号作为间隔符,并针对第二列来进行数值升序排序,结果很令人满意。

7 其他的sort常用选项

-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写

-c会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1

-C会检查文件是否已排好序,如果乱序,不输出内容,仅返回1

-M会以月份来排序,比如JAN小于FEB等等

-b会忽略每一行前面的所有空白部分,从第一个可见字符开始比较。

有时候学习脚本,你会发现sort命令后面跟了一堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,我们就来搞定它—-k选项!

1 准备素材

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

 

第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其他的别信,都瞎写的^_^)

2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)

$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

看到了吧,就直接用-k 1设定就可以了。(其实此处并不严格,稍后你就会知道)

3 我想让facebook.txt按照公司人数排序

$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

不用解释,我相信你能懂。

但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。

4  我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:

$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)

5 我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)

$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想想,再结合我们上一篇文章,能得到答案么?揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:

$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

看,我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。

6 -k选项的具体语法格式

要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:

[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。

先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。

C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。

FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。

同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

7 突发奇想,从公司英文名称的第二个字母开始进行排序:

$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000

看,我们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了。

8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:

$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。

9 在modifier部分还可以用到哪些选项?

可以用到b、d、f、i、n 或 r。

其中n和r你肯定已经很熟悉了。

b表示忽略本域的签到空白符号。

d表示对本域按照字典顺序排序(即,只考虑空白和字母)。

f表示对本域忽略大小写进行排序。

i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如\a是报警,\b是退格,\n是换行,\r是回车等等)

10 思考思考关于-k和-u联合使用的例子:

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

这是最原始的facebook.txt文件。

$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000

当设定以公司员工域进行数值排序,然后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。

$ sort  -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

$ sort  -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500

这个例子也同理,开头字符是g的guge就没有幸免于难。

$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

咦!这里设置了两层排序优先级的情况下,使用-u就没有删除任何行。原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的:)(不信,你可以自己加一行sina 100 4500试试看)

11 最诡异的排序:

$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。

第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。

又因为sort认为0小于00小于000小于0000….

因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)

答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:

$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

12 有时候在sort命令后会看到+1 -2这些符号,这是什么东东?

关于这种语法,最新的sort是这么进行解释的:

On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys.  POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.

原来,这种古老的表示方式已经被淘汰了,以后可以理直气壮的鄙视使用这种表示方法的脚本喽!

(为了防止古老脚本的存在,在这再说一下这种表示方法,加号表示Start部分,减号表示End部分。最最重要的一点是,这种方式方法是从0开始计数的,以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符。明白?)

Tagged as: Comments Off
26Dec/17

Window 下安装 Memcached

Posted by Nick Xu

官网上并未提供 Memcached 的Window平台安装包,我们可以使用以下链接来下载,你需要根据自己的系统平台及需要的版本号点击对应的链接下载即可:

在 1.4.5 版本以前 memcached 可以作为一个服务安装,而在 1.4.5 及之后的版本删除了该功能。因此我们以下介绍两个不同版本 1.4.4 及 1.4.5的不同安装方法:


memcached <1.4.5 版本安装

1、解压下载的安装包到指定目录。

2、在 1.4.5 版本以前 memcached 可以作为一个服务安装,使用管理员权限运行以下命令:

c:\memcached\memcached.exe -d install

注意:你需要使用真实的路径替代 c:\memcached\memcached.exe。

3、然后我们可以使用以下命令来启动和关闭 memcached 服务:

c:\memcached\memcached.exe -d start
c:\memcached\memcached.exe -d stop

4、如果要修改 memcached 的配置项, 可以在命令行中执行 regedit.exe 命令打开注册表并找到 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached" 来进行修改。

如果要提供 memcached 使用的缓存配置 可以修改 ImagePath 为:

"c:\memcached\memcached.exe" -d runservice -m 512

-m 512 意思是设置 memcached 最大的缓存配置为512M。

此外我们还可以通过使用 "c:\memcached\memcached.exe -h" 命令查看更多的参数配置。

5、如果我们需要卸载 memcached ,可以使用以下命令:

c:\memcached\memcached.exe -d uninstall

memcached >= 1.4.5 版本安装

1、解压下载的安装包到指定目录。

2、在 memcached1.4.5 版本之后,memcached 不能作为服务来运行,需要使用任务计划中来开启一个普通的进程,在 window 启动时设置 memcached自动执行。

我们使用管理员身份执行以下命令将 memcached 添加来任务计划表中:

schtasks /create /sc onstart /tn memcached /tr "'c:\memcached\memcached.exe' -m 512"

注意:你需要使用真实的路径替代 c:\memcached\memcached.exe。

注意:-m 512 意思是设置 memcached 最大的缓存配置为512M。

注意:我们可以通过使用 "c:\memcached\memcached.exe -h" 命令查看更多的参数配置。

3、如果需要删除 memcached 的任务计划可以执行以下命令:

schtasks /delete /tn memcached
21Dec/17

解决mysql占用IO过高

Posted by Nick Xu

1、日志产生的性能影响:
由于日志的记录带来的直接性能损耗就是数据库系统中最为昂贵的IO资源。MySQL的日志包括错误日志(ErrorLog),更新日志(UpdateLog),二进制日志(Binlog),查询日志(QueryLog),慢查询日志(SlowQueryLog)等。当然,更新日志是老版本的MySQL才有的,目前已经被二进制日志替代。

在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的。但是在一般稍微重要一点的实际应用场景中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件。有时候为了进一步的性能优化,定位执行较慢的SQL语句,很多系统也会打开慢查询日志来记录执行时间超过特定数值(由我们自行设置)的SQL语句。

一般情况下,在生产系统中很少有系统会打开查询日志。因为查询日志打开之后会将MySQL中执行的每一条Query都记录到日志中,会该系统带来比较大的IO负担,而带来的实际效益却并不是非常大。一般只有在开发测试环境中,为了定位某些功能具体使用了哪些SQL语句的时候,才会在短时间段内打开该日志来做相应的分析。所以,在MySQL系统中,会对性能产生影响的MySQL日志(不包括各存储引擎自己的日志)主要就是Binlog了。

2、mysql内执行如下指令:
set global sync_binlog=500;
当每进行500次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。
set global innodb_flush_log_at_trx_commit=2;
默认值1代表每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设置为2代表不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值设置为2只会在整个操作系统宕机时才可能丢数据。
Tagged as: , Comments Off
site
site