使用 Vagrantfile 配置虚拟机


configuring-vagrant-virtual-machine

Vagrantflie

在项目的目录下面有个名为 Vagrantfile 的文件,它是执行 vagrant init 命令时创建的一个虚拟机配置文件,这个配置文件包含项目使用的虚拟机的相关配置。

Vagrantfile 文件里的内容大部分都是注释内容,里面介绍了可用的配置选项还有相关的解释。去掉注释内容,实际有效的代码只有三行:

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
end

中间一行代码就是配置的主体内容,上面的这行配置指定了虚拟机使用的 Box 是 centos/7,可以在这个代码块中添加其他自定义的配置:

Vagrant.configure("2") do |config|
  # 配置内容放在这里
end

虚拟机网络配置

把虚拟机作为一台服务器,就需要将主机(电脑)与虚拟机之间通过网络连接在一起,网络中的其他设备也可能要跟虚拟机相连,这就需要配置虚拟的网络,让虚拟机可以被访问。

可以通过 Vagrantfile 去配置虚拟机的网络,Vagrant 提供了以下三种方法:

  • 端口转发 forwarded_port
  • 公有网络 private_network
  • 私有网络 public_network

启动虚拟机后,虚拟机可以使用 nat 方式上网,即如果本机电脑能上网,虚拟机内部也可以上网。

在启动虚拟机返回的日志里,会有如下的相关配置:

==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)

上述配置意思是从主机使用 SSH 连接虚拟机的时候把主机(host)上的 2222 端口转发到虚拟机(guest)上的 22 端口。

可以通过 vagrant ssh 命令进入虚拟机内容,使用 ping 命令测试一下某个网站的连接。 继续阅读 “使用 Vagrantfile 配置虚拟机”

使用 Vagrant 管理虚拟机


vagrant-virtualbox-centos7

使用 Vagrant 可以很方便的管理虚拟机,只需要一行命令可以操作管理虚拟机,也可以重新打包成新的镜像,分享他人使用。

安装 Vagrant

可以通过 Homebrew 使用命令行安装,可以直接去 Vagrant 官网(https://www.vagrantup.com)下载安装包手动安装。

// 命令行安装 Vagrant
brew install Caskroom/cask/vagrant 

虚拟机需要用到虚拟机软件,比如 VirtualboxVMwareParallels Desktop 等等,因为 Virtualbox 开源且免费,所以此处使用 Virtualbox。安装 Virtualbox 同样可以通过命令行或者官网(https://www.virtualbox.org)下载安装包手动安装。

// 命令行安装 Virtualbox
brew install Caskroom/cask/virtualbox

Vagrant Box

Box 是 Vagrant 使用的一种包含虚拟机镜像、虚拟机配置和 Vagrant 配置的封装包文件。在 Vagrant 提供的云服务(https://vagrantcloud.com/)上可以下载到其他人制作好的 Box。

添加 Box

Vagrant 添加 Box 的命令为:

vagrant box add <name>

此处以 CentOS 7 为例,如果指定的 Box 在本地电脑上不存在,Vagrant 会到云上自动下载执行:

vagrant box add centos/7

安装成功后界面如下:

vagrant-add-box-virtualbox-centos7

完成以后,可以查看一下在本地上的 Box 列表:

vagrant box list

也可将 Box 手动下载到本地电脑上,再执行 vagrant box add 命令去手工添加 Box:

vagrant box add <name> <path>

升级 Box

检查是否有可用的升级,执行命令:

vagrant box outdated

返回:

Checking if box 'centos/7' is up to date...

执行升级:

vagrant box update

删除 Box

不再需要的镜像可以从电脑中删除掉,执行:

vagrant box remove <box name>

即使你删除了安装在电脑上的镜像,已经使用这个镜像创建的我虚拟机也仍然是可以正常使用的。不过为了更安全一些,你最好在删除镜像之前 ,先去销毁所有使用了这个镜像创建的虚拟机。 继续阅读 “使用 Vagrant 管理虚拟机”

使用 Homebrew 安装软件


homebrew-for-ma

Mac App Store 像是一个图形界面的包管理工具,也可以很方便的管理系统上软件。不过有很多软件是在 App Store 上找不到的,可以通过 Homebrew 这个包管理工具,使用命令行管理软件。

安装 Homebrew

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

使用 Homebrew

Homebrew 的命令以 brew 开头,后面接着具体的命令,例如:

// 查看帮助信息
brew help

// 安装包
brew install

// 升级已经安装的包
brew upgrade

搜索包

搜索能够使用 Homebrew 安装的东西,使用的命令是 brew seach,后面加上搜索的关键词:

brew search <keyword>

访问某个包的可以使用 brew home 命令,再加上包的名字,就可以直接在浏览器中打开包的主页:

brew home <package>

安装

安装包的命令是 brew install,后面加上包的名字.

brew install <package>

一般用 Homebrew 安装的东西都是一些命令行的工具,这些工具大部分都是开发的时候要用的,不过你会看到一些 Cask 开头的包,Cask 扩展了 Homebrew ,它可以让我们用 Homebrew 去安装一些带图形界面的软件。

查看使用 brew 包装的东西,使用命令:

brew list

升级

升级 Homebrew 本身使用 brew update 命令,升级已经安装的包,使用 brew upgrade 命令,如果后面不加具体包的名字,Homebrew 会升级所有已安装的包,如果升级具体的某个包,需要在命令后面加上包的名字:

brew upgrade <package>

升级 cask 安装包

Homebrew upgrade 升级命令并不能直接升级 cask 安装的软件,需要单独下载安装包手工更新,不过可以给 Homebrew 安装一个扩展工具:brew-cask-upgrade 来实现命令升级 Cask 安装包。

安装 brew-cask-upgrade:

brew tap buo/cask-upgrade

安装完成后,就可以直接使用命令行升级 Cask 安装包了,执行:

brew cu

如果想单独升级某一个安装包,可以在命令后添加具体的 Cask 名称:

brew cu [cask]

brew cu 命令后还可以添加一些控制选项:

Usage: brew cu [CASK] [options]
    -a, --all          Include apps that auto-update in the upgrade
        --cleanup      Cleans up cached downloads and tracker symlinks after updating
    -f  --force        Include apps that are marked as latest (i.e. force-reinstall them)
    -y, --yes          Update all outdated apps; answer yes to updating packages

使用命令 brew help cu 可以查看命令的帮助信息。

删除

删除 Homebrew 安装的包,使用命令 brew uninstall,后面加上要删除的包的名字:

brew uninstall <package>

Swift 笔记:可选类型与 nil


可选类型

使用可选类型(Optionals)来处理值可能缺失的情况。可选类型表示:

  • 有值,等于 x

或者

  • 没有值
let pNum = "123"
let cNum = Int(pNum)
// cNum 被推测类型为 "Int?",或类型 "Optional Int"

问号暗示包含的值是可选类型,也就是说可能包含 Int 值也可能不包含值

nil

可选变量赋值为 nil 来表示它没有值。
nil 不能用于非可选有常量和变量。
如果在声明一个可选常量或变量时没有赋值,它们会自动被设置为 nil

if 语句以及强制解析

使用 if 语句和 nil 来比较判断一个可选值是否包含值,使用“相等”(==)或“不等”(!=)来执行比较。

当确定可选类型确实包含值时,可以在可选值的名字后面加一个感叹号(!)来获取值。这被称为可选值的**强制解析(Forced Unwrapping):

let possibleNum = "123"
let convertedNum = Int(possibleNum)

if convertedNum != nil {
    print("convertedNum has an integer value of \(convertedNum!).")
}

可选绑定

使用可选绑定(Optional Binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时变量或者变量:

if let constantName = someOptional {
    statements
}

隐式解析可选类型

可选类型第一次被赋值后,可以确定总会有值,这种类型的可选状态被定义为隐式解析可选类型(Implicitly Unwrapped Optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。

命令行基础


command-line

查看当前位置:pwd

使用 pwd (Print Working Directory)命令 查看自己当前所在的位置路径。

Ryans-MacBook-Pro:~ ryan$ pwd
/Users/ryan

显示当前目录下的东西:ls

想要查看某个目录下面都有什么东西,使用 ls 命令,在命令的后面可以指定一个路径,这样会显示这个指定路径里东西,直接使用 ls 会显示当前所在位置里的内容。

mac-terminal-ls

Mac 终端上使用 ls 只能简单的显示文件目录与名称,想要得到更详细的信息可以在命令后面加上 -l 参数,如果需要把隐藏文件也显示出来,则需要添加 -a 参数。

mac-terminal-ls-la

显示具体路径下的内容,可以 ls 命令后面加上具体的路径,可以是相对路径,也可以是绝对路径。

// 这是一个相对路径
ls desktop

// 这是一个绝对路径
ls /Users/ryan/desktop

清空命令行上面的显示:clear

使用 clear 命令来清空命令行。Windows 也可以使用 cls 命令,Mac 上可以使用快捷键 command+K

路径中的符号

  • ~:用户主目录
  • /:系统根目录
  • ./:当前目录
  • ../:上一级目录

进入到某个目录下面:cd

想要进入到某个目录下面,需要使用 cd(Change Directory)这个命令,后面加上想要进入的路径。

cd 目标路径

// 可以使用相对路径
cd desktop

// 也可以绝对路径
cd ~/desktop

创建目录:mkdir

在指定的地方创建一个新的目录,可以使用 mkdir(Make Directory),后面加上要创建目录的名字。

// 在当前位置创建一个目录
mkdir 目录名

如果需要创建一个目录结构,即在某个目录下面,再创建一个子目录,需要在 mkdir 命令后添加一个 -p 参数。

// 创建一个目录结构
mkdir -p 目录名/子目录名/子目录名

创建空白文件:touch

创建一个空白的文件可以使用 touch 命令:

touch 文件名

查看文件内容:cat/tail

输出某个文件里的内容,可以使用 cat 命令:

cat 文件名

如果只是查看文件中的一小部分内容,可以使用 tail 命令:

tail 文件名

移动目录与文件:mv

把目录或文件移动到一个新的位置,使用 mv(Move)命令,这个命令也可以用来重命名目录或者文件。命令的后面先是目标目录或文件,再是新的位置路径。

mv 源目录/文件 目标路径

注意

  • 如果目标路径不存在,就会把源目录重命名成目标路径。
  • 在移动文件夹的时候,文件移动到的位置结尾一定要加上 /,不然 mv 命令会把想要移动的文件重命名成想移动到的那个位置。

复制目录与文件:cp

cp (Copy)命令可以复制指定的文件或者目录。

// 复件文件到指定路径
cp 源文件 目标路径

要复制目录,需要加一个 -R 参数。

// 复制目录
cp -R 目录名 目录重命名

删除目录与文件:rm

删除指定的目录或者文件,使用 rm(Remove)命令,如果要删除目录,需要添加一个 -r 参数,另外,可以添加一个 -f 参数,这样删除目录里的文件时不会出现提示。

// 删除文件
rm 文件名

// 删除目录
rm -r 目录名
rm -rf 目录名

Swift 笔记:数据类型


常用数据类型

  • Int: 整数型
  • Float: 32 位浮点数
  • Double: 64 位浮点数
  • Boolean: 布尔值
  • String: 字符串
  • Tuples: 元组

Int

一般来说,不需要专门指定整数的长度。Swift 提供了一个特殊的整数类型 Int,长度与当前平台的原生字长相同:

  • 在32位平台上,IntInt32 长度相同。
  • 在64位平台上,IntInt64 长度相同。

除非需要特定长度的整数,一般来说使用 Int 就够了,这可以提高代码一致性和可复用性。

对于比较大的数值,Swift 可以使用下划线 _ 来分隔位数:

let a = 1_000_000
let b = 1_000_000

UInt

Swift 也提供了一个特殊的无符号类型 UInt,长度与当前平台的原生字长相同。

注意:
尽量不要使用UInt,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用Int,即使你要存储的值已知是非负的。统一使用Int可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推断。

浮点数

Double 表示 64 位浮点数,Float 表示 32 位浮点数。Double 精确度很高,至少有 15 位数字,而 Float 只有 6 位数字,在两种类型都匹配的情况下,优先选择 Double

类型转换

值不能被隐式转换,如果需要转换为其他类型,必须进行显式转换:

let label = "The width is "
let width = 90
let widthLabel = label + String(width)

也可把值写到括号中,同时在括号之前写一个反斜杠来进行类型转换:

let widthLabel = label + "\(width)"

布尔值

Swift 有两个布尔常量,truefalse

元组

元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。

let http404Error = ( 404 , "Not Found!" )

元组可以在常量或变量名后使用冒号加括号的形式标注数据类型:

let http200Status: ( Int , String ) = ( 200 , "OK!" )

可以将一个元组的内容分解(decompose)成单独的常量和变量:

let ( errorCode , errorMessage ) = http404Error

也可以通过下标来访问元组中的单个元素,下标从零开始:

let point = ( 5 , 2 )
point.0
point.1

可以在定义元组的时候给单个元素命名。给元组中的元素命名后,就可以通过名字来获取这些元素的值:

let point = ( x: 5 , y: 2)
point.x
point.y

也可以在标注数据类型时给单个元素命名:

let point: ( x:Int , y:Int ) = ( 6 , 2 )
point.x
point.y

元组分解时需要忽略的元素使用下划线 _ 来标记:

let loginResult = ( true , "Ryan" )
let ( isLoginSuccess , _ ) = loginResult
if isLoginSuccess {
    print("Login Success!")
    }
else{
    print("Login Failed!")
    }

输出函数:print

使用函数 print(_:separator:terminator:) 来输出当前常量或者变量的值。

var x = 1 , y = 2 , z = 3

print ( x , y , z , separator:"---")
// 输出结果为 1---2---3

print ( x , terminator:":)")
// 输出结果为 1:)

separatorterminator 参数具有默认值,调用时可以忽略。默认情况下,separator 使用空格作为间隔符,terminator 使用换行符来结束当前行。如果不想换行,可以传递一个空字符串给 terminator 函数:

print ( someValue , terminator:"" )

Swift 笔记:常量与变量


使用 let 声明常量,使用 var 声明变量。常量的值一旦设定就不能改变,而变量的值可以随意更改。

命名

可以使用任意字符作为常量或变量名称,包括 Unicode 字符。为保证代码的可读性,通常情况下常量或变量名称使用除首单词外其余单词首字母大写的方式命名:

let 😀 = "smile"
let myWebsite = "https://iiiryan.com"

常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开头,但是可以在常量与变量名的其他地方包含数字。

一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。

分号

单行语句末尾可以不添加分号 ;,但有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:

let a = 5 ; print(a)
// 输出 a

单行语句可以同时声明多个变量或常量,使用 , 分隔。

var myVariable = 10
let myConstant = 8

var a = 1 , b = 2 , c = 3

类型标注

Swift 是一种强类型语言,编译器会根据声明赋值自动推断数据类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。

var str = "Hello, Swift!"
var myWebsite: String = "https://iiiryan.com"

注释代码

单行注释以双正斜杠 // 作为起始标记,多行注释以 /* 开始,以 */ 结束。
多行注释可以嵌套在其它的多行注释之中

Mac 技巧:禁止生成 .DS_Store 文件


.DS_Store 是 macOS 保存文件夹的自定义属性的隐藏文件,如文件的图标位置或背景色,相当于Windows的desktop.ini。

禁止 .DS_store 生成,执行以下命令:

defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE2

恢复 .DS_store 生成,执行:

defaults delete com.apple.desktopservices DSDontWriteNetworkStores

Mac 技巧:不带阴影效果的窗口截图


mac-tips-take-a-screenshot-without-the-shadow-effect

默认情况下,macOS 系统自带的窗口截图(Command(⌘) + Shift(⇧) + 数字键4)会自带一个阴影效果,有的时候这个阴影效果插入到文档中会影响整个排版效果。

当然,你可以直接使用命令行禁用这个效果(How to remove the shadow from screenshots you take on your Mac),但如果只对当前截图取消阴影效果该怎么做呢?

  • 在 Mac 键盘上同时按下 Command(⌘) + Shift(⇧) + 数字键4,进入截图模式,鼠标指针变为十字准线图标。
  • 按一下空格键,使光标更改为相机符号,表示将捕获特定窗口的屏幕截图。
  • 然后按住 Option(⌥),将光标放在要截图的窗口上,然后按鼠标左键获取所选窗口的图像,这样就不会出现烦人的阴影效果了。:)

提示:

如果要将截图保存在系统剪贴板中,以便在其他应用程序(以及设备,通过通用剪贴板)中快速粘贴,可以使用 Control(^)Command(⌘)Shift(⇧)数字键4,而不是 Command(⌘)Shift(⇧)数字键4

要取消屏幕截图,只需点击 esc 键即可。