基于Appium、Python的自动化测试环境部署和实践

 

第一章 导言

1.1 编制目的

该文档为选用Appium作为移动设备原生(Native)、混合(Hybrid)、移动Web(Mobile Web)应用UI自动化测试的相关自动化测试人员、开发人员等提供参考。

1.2 预期读者

自动化测试人员、测试代表、开发人员等。

第二章 概述

2.1 Appium设计哲学

不需要为了自动化而且重新编译或修改测试app;

不应该让移动端自动化测试限定在某种语言和某个具体的框架;也就是说任何人都可以使用自己最熟悉最顺手的语言以及框架来做移动端自动化测试;

不要为了移动端的自动化测试而重新发明轮子,重新写一套惊天动地的api;也就是说webdriver协议里的api已经够好了,拿来改进一下就可以了;

移动端自动化测试应该是开源的;

2.2 Appium技术框架(C/S 框架)

Appium的核心是一个暴露了一系列REST API的Server。这个server的主要功能:监听一个端口,然后接收由client发送来的命令(command)。解析这些command,把这些command转成移动设备可以理解的形式发送给移动设备,然后移动设备执行完这些command后把执行结果返回给server, server再把执行结果返回给client。

client就是发起command的设备,一般来说就是我们代码执行的机器,执行appium测试代码的机器。狭义点理解,可以把client理解成是代码,这些代码可以是java/ruby/python/js的,只要它实现了webdriver标准协议就可以。

这样的设计思想带来了一些好处:

1)多语言的支持;

2)可把server放在任意机器上,支持云测试;

图1 Appium架构

图2 Appium Android模型

图3 AppiumiOS模型

2.3 Appium Server/Client

Appium Server即服务器,连接Appium客户端和移动设备。原生的webdriverapi为web端设计,因此扩展到移动端要拓展。Appium官方提供了一套appium client,涵盖多种语言ruby/java/python等。

2.4 会话Session

在webdriver/appium,所有测试都必须在Appium Server和移动设备之间创建会话(Session)后才可以进行。一般来说,通过POST/session这个URL,然后传入会话属性(Desired Capabilities)就可以开启会话了。开启会话后,会返回一个全局唯一的会话ID(session id),之后几乎所有的请求都基于该会话ID,该会话ID代表了你所打开的浏览器或者是移动设备的模拟器,连接执行机器和移动设备。由于每个移动设备的连接会话ID是全局唯一的,那么在同一台机器上启动多个会话就变成了可能,这使多移动设备的并发测试成为可能。

会话属性(Desired Capabilities)包含会话配置信息,以key-value形式存在,可以理解成是java里的map,python里的字典,ruby里的hash以及javascript里的json对象(实际上,Appium Server和移动设备之间的会话属性就是通过json对象传输)

第三章 Appium安装

Appium Windows版仅支持Android设备(手机),Appium Mac版同时支持Android和iOS设备(手机)。

3.1 Windows版安装(64位)

3.1.1 软件列表

1)JDK> 1.6

2)vcredist_x86_c++

3).Net Framework > 4.0

3)Android Developer Tools(ADT-Bundle-windows-x86-64)

4)Appium for windows(最新版1.4.16.1)

5) Appium client(根据使用的语言安装一种即可:Java/Python/Ruby等),对于Java客户端,还需要Selenium包selenium-java-2.46.0.jar , selenium-server-standalone-2.46.0.jar,python的是Appium-python-client(就是一个python类库)

6)Android手机驱动(for windows),windows必须安装任意一个Android手机驱动,否则,adb无法检测无设备。

3.1.2 安装过程

按照JDK、vcredist_x86_c++、.NET Framework、Appium的顺序安装好各软件,ADT直接下载就可以用无需安装

1)JDK安装:设置系统环境变量JAVA_HOME为JDK安装路径:(Java安装和环境变量配置,自行百度)

2)vcredist_x86_c++安装:百度下载vcredist_x86_c++.exe文件,双击安装即可。

3).NET Framework安装:百度一个大于4.0版本的.NET Framework.exe文件。双击安装即可。

4)Appium服务端安装:下一个Appium for windows 1.4.16版本,双击安装即可。(注:Appium分为客服端和服务端,服务端就是Appium工具,又可以分为GUI版本和终端版本。GUI版本是可视化的图像界面工具,终端版本是在终端启动的一个服务而已。客服端就是针对python、java、ruby等语言开发的类库)

5)ADB安装:ADB是ADT的一个工具,所以,在要下一个ADT的安装包(免安装的)解压即可。然后,设置系统环境变量ANDROID_HOME为ADT所在目录(比如D:\Mobile-AutoTest-Software\adt-bundle-windows-x86_64-20130917\sdk),同时把并把ADT里的tools和platform-tools两个目录加入到系统的 Path路径里:注意:adb需要安装adb驱动,一般手机驱动自带adb驱动,所以只要安装一个手机驱动即可

                                  

adb安装成功后在终端输入adb devices会弹出PC端连接的设备的udid

                    

6)python安装:下一个python2.7的安装包,双击安装即可。如果需要通过python安装相关的python类库,还要安装pypa-setuptools、pip等工具。

6)Appium客服端安装:安装Appium Client(客户端只需安装一个,比如Python的或者Java的)这里以python为例:

1、需首先安装Python、pypa-setuptools、pip等Python环境(安装过程自行百度),然后通过pip在线(PC需联网)安装Selenium及Python客户端(cmd下切换到Python安装目录C:\Python27\Lib\site-packages\后执行):

python pip install Selenium

python pip install Appium-Python-Client

2、设置环境变量,把Python的目录加到系统的Path路径里

小提示:

安装Appium-Python-Client客户端时有时会遇到setuptools版本问题,运行python pip install –upgrade setuptools升级后再安装:

                    

如果机器没联网,下载Selenium和Appium-Python-Client,并解压把整个目录放到Python安装目录(一般是C:\Python27\Lib\site-packages 目录下),如下图(selenium-2.53.1目录下py目录的selenium目录拷贝到上面的site-packages目录)

                    

 

Java客户端可直接下载Jar包(比如java-client-3.2.0.jar),在Java工程中添加Jar即可。

其他客户端安装【略】

按照如上步骤安装好各软件后,基本环境就算完成了。启动Appum,填写被测APP路径,Platform选Android,Automation Name选Appium,PlatformVersion根据手机的Android版本选择,DeviceName选择上面adb命令识别的手机udid号;Server地址和端口保持默认:

配置上面两项内容后,点击启动按钮,看到最后一行信息及表示启动成功:

3.2 Mac版安装

3.2.1 软件列表

Mac Pro (OS X 10.10.3)

JDK > 1.6

Appium for Mac(最新版Appium-1.4.13.dmg)

Xcode 7.X

Appium Client(Python、Java等),对于Java客户端,还需要Selenium包selenium-java-2.46.0.jar , selenium  -server-standalone-2.46.0.jar

3.2.2 Appium安装过程

  1. 安装brew :终端输入ruby –e "$(curl –fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/install)"
  2. 安装node.js:到官网http://nodejs.org下载Mac的pkg安装包,下载完成直接安装即可无需配置任何参数。在终端输入node –version 如有版本号出来这说明成功。(也可以通过brew、来安装:brew install node)
  3. 获取权限:sudo chmod –R  777 /usr/local/
  4. 安装ideviceinstaller:brew update  ,brew install ideviceinstaller
  5. 安装Appium服务端:npm install –g appium@1.4.16,npm install wd(还有问题就看这篇文章:www.15yan.com/story/4GbuTwXQKDU/)
  6. 安装pip:sudo easy_install pip就行。
  7. 安装appium python client和selenium(客服端):pip install Appium-Python-Client,pip install selenium

过程和Windows基本一致,JDK安装过程自行百度,python咋Mac和Linux环境下是自带的无须安装。环境变量JAVE_HOME和ANDROID_HOME设置,并把ADT里的platform-tools和tools加到系统目录:

最后,启动Appium-doctor检查环境配置,全部打勾说明环境搭建完毕:

3.2.3 针对iOS10升级appium到1.6.3解决方案

由于iOS10放弃了uiautomator,改用XCUITest来进行测试。appium1.6.0之前的版本全部采用uiautomator来进行自动化测试,基于这次iOS的调整,appium1.6.0之后的版本添加了WebDriverAgent依赖来应对这次iOS的调整。这里,我针对appium1.6.3的升级过程做描述。

  1. 安装carthage,brew install carthage
  2. 安装xcpretty,gem install xcpretty
  3. 在安装好appium旧版情况下,卸载appium。npm uninstall –g  appium.
  4. 安装appium1.6.3,npm install –g appium。(这个过程会很难成功,但是,我们能做的就是不停尝试,直到安装成功为止。)
  5. 安装WebDriverAgent,cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent(如果不在此目录,自行查找)
  6. mkdir –p Resources/WebDriverAgent.bundle
  7. sh ./Scripts/bootstrap.sh –d(这步可能会报错,去下一个vpn,开启服务,再次下载就ok了,这里推荐“star vpn”很不错的vpn)
  8. cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent用xcode打开WebDriverAgent.xcodeproj。修改项目的Bundle identifier.要包Bundle identifier的Facebook改成其他东西。Signing,要选Automatically manage signing,开发者选自己的账号或者用证书进行编译,项目的所有bundle identifier都要该。改完后, build。
  9. 关闭xcode,在终端cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent。
  10. xcodebuild –project WebDriverAgent.xcodeproj –scheme WebDriverAgentRunner –destination 'id=真机的udid' test.
  11. 如果运行结果报错为“Test target WebDriverAgentRunnerencounted an error (Early unexpected exit,operationnever finished bootstrapping –no restart will be attempted)”则忽略不计。
  12. 到此升级工作完成,注意:在安装WebDriverAgent到手机的时候必须保持手机连接外网。当然,在使用的过程中同样要连接外网。(如果WedDriverAgent是用证书进行编译的则在使用过程中不用连接外网)
  13. 由于,appium1.6.3为推出GUI版本,这里做元素定位的时候,我们用macaca进行定位,macaca安装教程网上查询。
  14. app-inspector是macaca的元素定位工具,使用命令,在终端输入:app-inspector –u "设备的udid"

3.3 Linux版安装

3.3.1 软件列表

Linux Ubuntu Destop 14.04以上版本

brew

ruby

git

curl

node

jdk

appium

Android sdk

Python Appium客户端:Appium-Python-Client、Selenium

3.3.2 安装过程

Appium Server 的安装

【参考https://coderwall.com/p/rcvkrq/install-nodejs-using-homebrew-and-install-appium

1. 删除nodejs :  sudo apt-get remove nodejs。但是默认的系统nodejs没有,这一步可做可不做。

2. 安装ruby:sudo apt-get install ruby

确认ruby 安装成功:

ruby -v有ruby的版本信息。

3. 安装git:sudo apt-get install git

4. 安装brew:ruby -e "$(wget -O- https://raw.github.com/Homebrew/linuxbrew/go/install)"

如果上面执行不成功的话可以用下面这句git clone https://github.com/Homebrew/linuxbrew.git ~/.linuxbrew

5. 安装curl:sudo apt-get install curl

6. 安装node.js:一定不能用sudo,直接普通用户安装(确认之前文件环境配置好后,如果安装下载失败多试几次)

brew install node

如果上面执行不成功的话就用这种方法:sudo apt-get install g++。

sudo apt-get install libssl-dev。

wget http://nodejs.org/dist/v5.6.0/node-v5.6.0.tar.gz

tar zxvf node-v5.6.0.tar.gz。

./configure(注:这句话要切到node的bin目录下执行)。

make。

     make install。

sudonpm install –g express-generator@4(全局模式安装)。

可能会比较慢(本机安装15分钟左右),耐心等待nodejs安装成功。

查看安装完成

node -v

7. 安装 Java 虚拟机

下载JDK,下载最新Java SDK

解压安装

我们把JDK安装到这个路径:/usr/lib/jvm

如果没有这个目录(第一次当然没有),我们就新建一个目录

1)cd /usr/lib

2)sudo mkdir jvm

建立好了以后,我们来到刚才下载好的压缩包的目录,解压到我们刚才新建的文件夹里面去,并且修改好名字方便我们管理,(根据版本名自己修改名字)

1)sudo tar zxvf ./jdk-7-linux-i586.tar.gz  -C /usr/lib/jvm

2)cd /usr/lib/jvm

3) sudo mv jdk1.7.0_05/ jdk7

配置JAVA环境变量

gedit ~/.bashrc

在打开的文件的末尾添加

export JAVA_HOME=/usr/lib/jvm/jdk7

export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

export PATH=${JAVA_HOME}/bin:$PATH

保存退出,然后输入下面的命令来使之生效

source ~/.bashrc

配置默认JDK

由于一些Linux的发行版中已经存在默认的JDK,如OpenJDK等。所以为了使得我们刚才安装好的JDK版本能成为默认的JDK版本,我们还要进行下面的配置。

执行下面的命令:

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk7/bin/java 300

sudo update-alternatives --install /usr/bin/javacjavac /usr/lib/jvm/jdk7/bin/javac 300

注意:如果以上两个命令出现找不到路径问题,只要重启一下计算机在重复上面两行代码就OK了。

执行下面的代码可以看到当前各种JDK版本和配置:

sudo update-alternatives --config java

测试

打开一个终端,输入下面命令:

java -version

显示结果(JDK1.8):

java version "1.8.0_05"

Java(TM) SE Runtime Environment (build 1.8.0_05-b05)

Java HotSpot(TM) Server VM (build 23.1-b03, mixed mode)

这表示java命令已经可以运行了。

8. 安装appium

全局安装appium,本机安装的是1.4.16版本(如果不加版本名会自动安装最新版本),通过npm淘宝镜像

通过config命令

npm config set registry https://registry.npm.taobao.org (这里是为下面一句服务的,即把appium的下载数据源指向淘宝库)

npm install -g appium@1.4.16

如果安装失败就用root账号进行安装?安装完之后,

cd /usr/local/lib

sudo chown –R  主机名字 node_modules

然后卸载:

npm uninstall appium –g

之后再普通用户下启动appium

可能会比较慢,耐心等待安装成功,如果安装失败重复执行安装命令(如果之前有安装过错误的版本,提示得删除之前的文件,删除之后在安装)。

安装成功会出现树状依赖关系图

查看版本

appium -v

9. 下载安装Android SDK Starter Package

Android SDK Starter Package这个只是SDK的核心基本工具,有了它,再利用它的管理工具下载其他你需要到部分。看到这个目录中有个android脚本文件了吗?执行它,就会启动Android SDK and AVD Manager,这个工具可以帮你下载其他你需要的部分,还可以创建模拟机。

下载地址是:http://developer.android.com/sdk/index.html,不过国内这个地址被墙掉了,你要想版本下载包了。

一般是下载最新版,我下载的:android-sdk_r21.1-linux.tgz。

wget http://dl.gmirror.org/android/android-sdk_r24.4.1-linux.tgz

接下来当然是解包了:tar zvxf android-sdk_r21.1-linux.tgz

解包完毕,就会在当前目录下出现android-sdk-linux_x86目录了。这个目录下就是sdk的基本工具了。记住这个目录,因为以后你运行工具或者设置ADT的时候,会需要这个目录的!。

注意,需要安装ia32-libs

sudo apt-get install -y libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5 lib32z1

配置 Android SDK

配置 Android 环境变量,将下面的变量添加到环境变量当中去(根据自己sdk存放的文件夹修改路径,注意HOME就为当前用户目录下)

export ANDROID_HOME="$HOME/adt/sdk"

export PATH=${PATH}:~/adt/sdk/tools

export PATH=${PATH}:~/adt/sdk/platform-tools

然后source

source ~/.bashrc

10. 安装Appium客户端(ubuntu系统自带python2.7和python3.4版本)

安装Appium-Python-Client(使用pip安装)

sudo apt-get install python-pip

sudo pip install Appium-Python-Client

(可能会失败,多试几次)

安装 selenium 2.0(/usr/local/lib/python2.7/dist-packages下也有就无需安装)

sudo apt-get install selenium

测试Appium

测试appium环境安装正确与否

appium-doctor

所有环境都打钩为正确配置好环境,查看上面的JAVA_HOME和ANDROID_HOME环境配置是否正确

命令行敲入appium

出现 welcome to appium v1.4.16 代表安装成功

测试项目

将项目放到/python2.7/dist-packages文件夹下测试运行

完成!!!

第四章 控件识别

4.1 控件识别(Windows)

启动Appium后,用Appium Inspector进行控件识别(如下图),可以进行点击和输入操作(Tap、Text),右边的界面会根据操作实时更新,方便连续识别控件。

4.2 控件识别(Mac)

启动Appium后,用Appium Inspector进行控件识别(如下图)。

4.3 tips

Appium终端版本启动命令:

Linux下启动命令:appium -a 127.0.0.1 -p 端口号 -bp 端口号 --session-override --no-reset

Mac下启动命令:appium -a 127.0.0.1 -p 端口号 -bp 端口号 --session-override --no-reset --tmp 绝对路径

Mac下启动多个appium(小于1.6.0的版本)会有冲突,所以必须要对每个appium自定一个不同的数据缓存目录。因此,tmp后面的参数不能相同。appium(大于1.6.0)由于引进了WebDriverAgent,同时运行个appium客户端会导致wda的pc端端口重复,可以在测试脚本中指定setCapability("wdaLocalPort","端口一"),确保每个appium客户端wdaLocalPort端口不同。

Appium长时间运行报错:FATAL ERROR:CALL_AND_RETRY_LAST Allocation failed – process out of memory 已放弃(核心已转储)。判断为node内存溢出。这是node的bug。

第五章 python脚本实例

driver对象类

from appium import webdriver
import time
from selenium.common.exceptions import NoSuchElementException class driverObject:
def __init__(self, host, port, platform, version, deviceName, noReset, unicodeK, resetK, appPath ,appP_bdId, appA_udid, localPort):
#__appP_bdId = "com.yitong.fjnx.mbank.android"
__appP_bdId = appP_bdId
#__appA_udid = ".Splash"
__appA_udid = appA_udid
self.pwmode = 'lower'
self.model='Appium'
self.desired_caps = {}
self.desired_caps['platformName'] = platform
self.desired_caps['platformVersion'] = version
self.desired_caps['noReset'] = noReset
self.desired_caps['unicodeKeyboard'] = unicodeK
self.desired_caps['resetKeyboard'] = resetK
self.desired_caps['app'] = appPath
self.desired_caps['udid'] = deviceName
self.desired_caps['deviceName'] = deviceName # Android - ignored, iOS - iPhone name
if platform == "Android":
self.desired_caps['appPackage'] = __appP_bdId
self.desired_caps['appActivity'] = __appA_udid
if platform == "iOS":
self.desired_caps['bundleId'] = __appP_bdId
self.desired_caps['automationName'] = 'XCUITest'
self.desired_caps['wdaLocalPort'] = localPort
url = "http://" + host + ":" + str(port) + "/wd/hub"
self.driver = webdriver.Remote(url, self.desired_caps)
time.sleep(5)
def get_driver(self):
return self.driver
def quit(self):
self.driver.quit()

主类

from testClass import driverObject
if __name__ == '__main__':
driver = driverObject(参数...)
  ele = self.driver.find_elements_by_class_name("android.widget.Button")
ele[0].click()
time.sleep(5)
ele = self.driver.find_elements_by_class_name("android.widget.EditText")
ele[1].send_keys("account")
ele[2].send_keys("password")
ele = self.driver.find_elements_by_class_name("android.widget.Button")
time.sleep(2)
ele[0].click()
driver.quit()

 关于Appium、Python的测试脚本公共函数可以查阅Appium-Python-Api文档,里面记录Appium提供给python的公共函数。其实,测试脚本的大部分内容就是找控件、点击控件、输入内容、线程等待这些操作。

基于Appium、Python的自动化测试的更多相关文章

  1. appium+python+Windows自动化测试文档

    appium+python自动化测试文档 一.认识appium 1.    什么是appium appium是开源的移动端自动化测试框架: appium可以测试原生的.混合的.以及移动端的web项目: ...

  2. 基于appium的app自动化测试框架

    基于appium框架的app自动化测试 App自动化测试主要难点在于环境的搭建,appium完全是基于selenium进行的扩展,所以app测试框架也是基于web测试框架开发的 一.设备连接 (即构建 ...

  3. 基于Appium的APP自动化测试基础--美团APP的实例

    转:https://blog.csdn.net/Tigerdong1/article/details/80159156 前段时间用一种流行语言,一个主流工具,一个实用框架,写了一个美团app自动化测试 ...

  4. 基于Appium的UI自动化测试

    为什么需要UI自动化测试 移动端APP是一个复杂的系统,不同功能之间耦合性很强,很难仅通过单元测试保障整体功能.UI测试是移动应用开发中重要的一环,但是执行速度较慢,有很多重复工作量,为了减少这些工作 ...

  5. APP H5 混合自动化使用说明 [基于 Appium+Python 系列]

    背景 前几天接到H5开发人员那边的业务开发需求单,说想将H5接入到自动化系列中,特此记录分享一下. 环境前置准备 手机与电脑USB连接,开启USB调试模式,通过adb devices可查看到此设备. ...

  6. appium+python搭建自动化测试框架_Tools安装(一)

    作者的配置环境和版本: win10 + python3.6 +  Appium v1.4.16 1.下载node   https://nodejs.org/en/download/, 下载node.j ...

  7. appium+python搭建自动化测试框架_Appium元素定位(二)

    Appium元素定位: 工具:Android\android-sdk\tools    uiautomatorviewer.bat 1. id定位: self.driver.find_element_ ...

  8. 基于 appium 的 UI 自动化测试

    其中主要的目录和文件为: /MPTestCases ----------- 存放测试用例 /errorScreenShot ------------ 用例执行失败生成的错误截图 startTest.p ...

  9. appium+python+eclipse 自动化测试框架构建!

    经过几天的慢慢研究,现将所需用的自动化框架进行了构建,在后期的代码编写中,直接在框架中套用编写对应的module.case等即可,以此来简化测试方式,提高代码的编写效率与规范 基本的架构设计流程图,如 ...

  10. appium+python搭建自动化测试框架_TestAPP框架(三)

    Pycharm 创建 Project,搭建 APPTEST框架如下图:   1.框架功能 业务功能的封装 测试用例封装 测试包管理 截图处理 断言处理 日志获取 测试报告生成 数据驱动 数据配置 2. ...

随机推荐

  1. HDU 5937 Equation(DFS+剪枝)

    题目链接 Equation 给定1-9这9个数字各自的卡片数,求能构成形如$i + j = k$的等式个数 等式中$i,j,k$必须都为个位数 若两个等式中$i,j,k$不完全相等,则这两个等式为不同 ...

  2. Uncaught TypeError: window.showModalDialog is not a function

    if(window.showModalDialog == undefined){ window.showModalDialog = function(url,mixedVar,features){ w ...

  3. Java中泛型的Class<Object>与Class<?>的区别(转)

    Object是一个具体的类名,而?是一个占位符号,表示任何类型,只要是SomeClass类或者子类就可以. List<Object>可以放任何类对象. List<? extends ...

  4. SQL 列转行与行转列

    假设有张学生成绩表(tb)如下:Name Subject Result张三 语文 74张三 数学 83张三 物理 93李四 语文 74李四 数学 84李四 物理 94*/ -------------- ...

  5. PhoneGap_百度百科

    PhoneGap编辑 PhoneGap是一个用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的 快速开发平台.它使开发者能够利用iPhone,Android,Palm,Sym ...

  6. Qnap 中VM下的win7

    因工作需要alone了Qnap 中VM下的win7,更改冲突项:1. 电脑名2. 必需卸载虚拟网卡,因为克隆系统的MAC地址相同.    添加网卡,指定IP Address.Subnet mask.G ...

  7. 【每日Scrum】第六天(4.16) TD学生助手Sprint1阶段性成果

    TD学生助手Sprint1阶段性成果(4.16) 任务看板 站立会议内容 组员 昨天 今天 困难 签到 刘铸辉 (组长) 和叶姐,静姐修改页面布局和图片显示,保证界面的亲切. 和大家一起做演示PPT, ...

  8. Intel平台map

  9. Ubuntu引导出问题grub rescu模式下:“error : unknown filesystem”或者 找不到normal.mod 的解决办法

    感谢http://www.linuxidc.com/Linux/2012-06/61983.htm,因为参考了其中的内容. 下面是修改和完善. 问题原因: (win7,ubuntu双系统下) 强制关机 ...

  10. Linux命令之ln软链接

    用途:链接文件 默认情况下,ln命令产生硬链接. 最常用的参数是-s(建立符号连接Symbolic Link,也叫软连接),具体用法是: ln-s 源文件 目标文件 当我们需要在不同的目录用到相同的文 ...