0%

部分linux发行版网络配置GUI强制openconnect使用密钥,用户名-密码登录可以通过命令行实现:

sudo openconnect [域名或IP地址]:[端口号]

然后根据提示操作就可以了。

主要来源:在 Manjaro Linux 系统使用 Docker

提要

硬件平台还是百视通R3300-M …… 安装Manjaro Arm 21.04后已升级到21.08,内核版本 5.13.0-1-MANJARO-ARM #1 SMP PREEMPT Wed Jun 30 23:07:51 +03 2021 aarch64 GNU/Linux

安装Docker

sudo pacman -Syu
sudo pacman -S docker

启动服务

sudo systemctl start docker.service

添加到系统启动项

sudo systemctl enable docker.service

添加当前用户到Docker组

这样当前用户就有足够权限操作docker而不必sudo权限。

sudo usermod -aG docker $USER

换国内源

打开或创建 /etc/docker/daemon.json 文件:

{
    "registry-mirrors": [
        "https://registry.docker-cn.com"
    ]
}

registry.docker-cn.com 是 Docker 的官方中国镜像, 除此之外还有其他一些第三方镜像可选:

镜像 地址
Azure中国 https://dockerhub.azk8s.cn
中科大 https://docker.mirrors.ustc.edu.cn
七牛云 https://reg-mirror.qiniu.com
网易云 https://hub-mirror.c.163.com
腾讯云 https://mirror.ccs.tencentyun.com

保存文件之后重启一下 Docker 服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

其他操作

docker search redis
docker pull redis
docker pull redis:rc
docker images
docker run --name myredis -d redis
docker ps
docker stop myredis
docker rm myredis
docker info

安装Portainer CE

docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

下步计划

之前在docker里运行过dokuwiki,tiddlywiki,minecraft server等等。跑minecraft server性能不太行,破坏方块有明显卡顿。

生成密钥及配置(略)

网上教程有很多

生成站点并推送到github

hexo g -d

推送站点源码到github

.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
git add .
git commit -m 'hexo 源文件推送'
git push origin hexoSource

远程分支名用自己的

拉取源码到本地

git clone -b blogSource https://github.com/12321/12321.github.io.git

参考:manjaro 切换国内源及软件安装

同步时间

时间不准会造成SSL验证失败等一系列问题。同步方式如下:(https://wiki.manjaro.org/index.php/System_Maintenance#Time_and_Date)

user $ timedatectl set-ntp true
user $ sudo systemctl enable --now systemd-timesyncd

当然也可以用date手动设置。

换国内源

sudo pacman-mirrors -i -c China -m rank
sudo pacman-mirrors -g
sudo pacman -Syyu

安装ARU包管理工具

sudo pacman -S yay

原本想通过ARU安装RTL8189ETV启动,但是包依赖linux mainline kernel,貌似不行。手动编译也没成功。

pacman.conf选项自定义

添加了Color和ILoveCandy选项,第一个使pacman产生彩色输出,第二个把pacman下载进度条变成吃豆子,虽然没什么用还是设置了。

pacman常用命令

参考:Pacman Overview

  1. 安装更新

To update the package database and update all packages on the system

user $ sudo pacman -Syu

To force a full refresh of the package database and update all packages on the system. You must do this when switching branches or switching mirrors.

user $ sudo pacman -Syyu

To force a full refresh of the package database, update all packages on the system and allow packages to be downgraded. Downgrading should be only be needed when switching to an older branch. For example, switching from Testing to Stable.

user $ sudo pacman -Syyuu
  1. 搜索软件包

To search the Manjaro repositories for available packages you can use the command pacman -Ss keyword. It will search both the package name and the description for the keyword. For example, to search for packages containing the keyword smplayer you could use:

user $ pacman -Ss smplayer

You can search your installed packages in the same manner using -Qs instead of -Ss. To search your installed packages for smplayer:

user $ pacman -Qs smplayer

Once you have found a package you can use pacman -Qi to get more information about an installed packages or pacman -Si for packages in the repos. Following the example above you could use

user $ pacman -Si smplayer

Finally, for a list of all installed packages on your system, enter the following command:

user $ pacman -Ql

  1. 安装软件包
    To install a software package, the basic syntax is pacman -S packagename. However, installing a package without updating the system will lead to a partial upgrade situation so all the examples here will use pacman -Syu packagename which will install the package and ensure the system is up to date. For example, to install smplayer the command is:

    user $ sudo pacman -Syu smplayer

You will then be presented a list of software to install. You may notice this list has more packages than you requested. This is because many packages also have dependencies which are packages that must be installed in order for the software you selected to function properly.

Pacman can also directly install packages from the local system or a location on the internet. The format of that command is pacman -U packagelocation. For example, to install a copy of your package cache you could do something like:

user $ sudo pacman -U /var/cache/pacman/pkg/smplayer-19.5.0-1-x86_64.pkg.tar.xz

Alternatively, you could get it directly from one of Manjaro’s mirrors:

user $ sudo pacman -U https://mirror.alpix.eu/manjaro/stable/community/x86_64/smplayer-19.5.0-1-x86_64.pkg.tar.xz
  1. 删除软件包
    To remove a software package, the basic syntax is sudo pacman -R packagename. We could remove the smplayer package we installed above with:

    user $ sudo pacman -R smplayer

This will remove the package, but will leave all the dependencies behind. If you also want to remove the unneeded dependencies you could use pacman -Rsu packagename as seen in this example:

user $ sudo pacman -Rsu smplayer

Sometimes when you try to remove a package you will not be able to because there are other packages which depend on it. You can use pacman -Rc packagename to remove a package and everything that depends on it. Be careful to heed the above warning when using this option.

user $ sudo pacman -Rc smplayer

The most nuclear option is pacman -Rcs packagename. This will remove everything that depends on packagename and continue to do so on its dependencies. This should really only be used in exceptional circumstances such as when removing an entire desktop environment and trying not to leave anything behind.

Pacman usually also creates backup configuration files when deleting packages. To remove those, you can add n to any of the examples above. For example:

user $ sudo pacman -Rn smplayer
user $ sudo pacman -Rsun smplayer
user $ sudo pacman -Rcn smplayer

提要

这个盒子硬件没啥好说的了,前面介绍过。之前用它运行Armbian 20.10 Focal 没问题,但是balbes150弃坑后无人接手,前景不明,于是迁移到了Manjaro ARM。目前来看社区支持比较完善,更新及时,测试内核5.13(linux-aml)运行成功。

镜像

选择了Manjaro ARM 21.04。为什么没有选择更新的版本,比如21.06,还得从内核提起。21.04搭载主线5.11内核,测试启动R3300-M没问题,但是后续版本搭载的主线内核(测试了5.13)无法启动,提示phy phy-c000000.phy.0:phy poweron failed --> -22然后卡死,所以需要想办法卸载主线内核然后安装Amlogic分支。

https://github.com/manjaro-arm/vim2-images/releases/download/21.04/Manjaro-ARM-minimal-vim2-21.04.img.xz
https://github.com/manjaro-arm/vim2-images/releases/download/21.04/Manjaro-ARM-mate-vim2-21.04.img.xz
https://github.com/manjaro-arm/vim2-images/releases/download/21.04/Manjaro-ARM-kde-plasma-vim2-21.04.img.xz/
https://github.com/manjaro-arm/vim2-images/releases/download/21.04/Manjaro-ARM-xfce-vim2-21.04.img.xz/

官方提供的4个镜像中,minimal不含图形界面,经本人测试运行成功,其余带图形界面的镜像未经测试。

安装

和Armbian 20.10 Focal基本一致,修改extlinux.conf选择合适dtb(R3300-M使用meson-gxbb-p201.dtb),修改u-boot-s905为u-boot.ext(镜像里默认的u-boot.ext适用s905x和s912,不适用于R3300-M),然后启动盒子,完成设置,SD卡自动扩容,一切结束后自动重启完成安装进入系统。

系统更新(更换内核)

冻结内核

首先修改系统文件避免更新内核(现在更新系统就挂了)。所有Manjaro发行版均预装nano,所以:

sudo nano /etc/pacman.conf

找到IgnorePkg一行,取消开头注释,修改为IgnorePkg = linux,保存退出,执行sudo pacman -Syu更新系统。系统更新后,建议重启系统。

切换内核为linux-aml

执行

sudo pacman -S linux-aml

这步会删除主线内核,安装更合适的Amlogic分支内核。结束后重启系统,用uname -a查看,系统内核已更新为5.13。

收尾工作

再次编辑/etc/paman.conf,修改IgnorePkg = linuxIgnorePkg = linux-aml,毕竟在电视盒子这种非正式支持的设备上更新内核还是要谨慎一些,没必要别乱动内核。确实需要更新的情况下,提前备份好Image和initramfs-linux.img,方便回滚。

备注

  1. 经测试,系统写入emmc无法启动。
  2. 如果使用U盘启动,需要在extlinux.conf中指定usb-storage.quirks参数。例如:

APPEND root=PARTUUID=5418e4d8-02 rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 quiet splash plymouth.ignore-serial-consoles usb-storage.quirks=152d:1561:u

152d:1561为U盘vendor和product的ID号码。在linux下可以使用lsusb查看,Windows下也有类似小工具。
3. 无法使用root身份SSH登录,会提示密码错误。建议用普通用户连接后再切换身份。
4. 有线网卡Mac地址不固定,每次重启都会变化。
5. WIFI暂不可用,待进一步测试。
6. 类似21.06等感觉可以通过替换Image和initramfs-linux.img实现从内核从主线到Amlogic分支切换,有兴趣的可以测试。

pdftk删除页码脚本

最近把《Linux命令行与shell脚本编程大全》翻了一遍,想演练一下,于是写出了下面这个脚本,用于调用pdftk删除给定页码生成新文档。编写调试过程中,对bash函数传参、位置参数调用等概念有了更深入的理解,特别是shift,用于处理数量未知的位置参数格外好用。

#!/bin/bash
# 对pdftk的简单封装,用于删除指定的页码,以空格分隔,支持形如"5-7"的页码范围。页码输入不必按顺序,类似"12 6-8 1 3"输入是可以正常工作的。

#isPdftkinstalled作用为检查pdftk是否可用,若可用则执行pdftk --version
function isPdftkinstalled {
    echo
    if [ -z $(whereis pdftk | gawk '{print $2}') ]
    then
        echo "pdftk未安装或未加入PATH,请检查。"
        echo "提示:pdftk已加入Deepin官方源,您可以通过 sudo apt install pdftk 简单安装。"
    else
        echo $(pdftk --version)
    fi
    echo
}

#getCouples作用为对输入的页码进行处理,支持输入单页或页码范围,将其转换为数对(获取范围前后页码,以冒号分隔)
function getCouples {
    local couples=''
    local left_end=''
    local right_end=''
    while [ -n "$1" ]
    do      
        arg1=$(echo "$1" | gawk -F"[- ]" '{print $1}')
        arg2=$(echo "$1" | gawk -F"[- ]" '{print $2}')
        left_end=$[ $arg1 - 1 ]
        #对应页码范围情况
        if [ -n "$arg2" ]
        then
            right_end=$[ $arg2 + 1 ]
        else
        #对应单页情况
            right_end=$[ $arg1 + 1 ]
        fi
        couples=$(echo $couples $left_end:$right_end)
        shift
    done
    #数对排序处理,注意sort是针对行的排序,故需要将空格转换成换行
    couples=$(echo $couples | tr " " "\n" | sort -t ':' -k 1 -n)
    couples=$(refineCouples $couples)
    echo $couples
}

#refineCouples作用为合并相邻数对,供getCouples调用
function refineCouples {
    local args=''
    local isNabour=''
    local Num1=$(echo $1 | cut -d ":" -f1)
    local Num2=$(echo $1 | cut -d ":" -f2)
    local Num3=''
    local Num4=''
    shift
    while [ -n "$1" ]
    do
        Num3=$(echo $1 | cut -d ":" -f1)
        Num4=$(echo $1 | cut -d ":" -f2)
        isNabour=$[ $Num2 - $Num3 ]
        if [ $isNabour -eq 1 ]
        then
            Num2=$Num4
        else
            args=$(echo $args $Num1:$Num2)
            Num1=$Num3
            Num2=$Num4
        fi
        shift
    done
    args=$(echo $args $Num1:$Num2)
    echo $args
}

#generateRanges作用为将数对转换为pdftk可用的页码范围
function generateRanges {
    local first_Bit=$(echo $1 | cut -d ":" -f1)
    local Num1=''
    local Num2=''
    local args=''
    while [ -n "$1" ]
    do
        Num1=$(echo $1 | cut -d ":" -f2)
        if [ -n "$2" ]
        then
            Num2=$(echo $2 | cut -d ":" -f1)
            if [ $Num1 -gt $Num2 ]
            then
                Num2=$Num1
            fi
        else
            Num2="end"
        fi
        shift
        args=$(echo $args $Num1-$Num2)
    done

    if [ $first_Bit -gt 0 ]
    then
        args=$(echo 1-$first_Bit $args)
    fi
    echo $args
}

#此函数作用为合并相邻页码范围,在使用refineCouples后已无使用必要,可删除
function refineRanges {
    local args=''
    local isNabour=''
    local Num1=$(echo $1 | cut -d "-" -f1)
    local Num2=$(echo $1 | cut -d "-" -f2)
    local Num3=''
    local Num4=''
    shift
    while [ -n "$1" ]
    do
        Num3=$(echo $1 | cut -d "-" -f1)
        Num4=$(echo $1 | cut -d "-" -f2)
        isNabour=$[ $Num3 - $Num2 ]
        if [ $isNabour -eq 1 ]
        then
            Num2=$Num4
        else
            args=$(echo $args $Num1-$Num2)
            Num1=$Num3
            Num2=$Num4
        fi
        shift
        echo $Num1
    done
    args=$(echo $args $Num1-$Num2)
    echo $args   
}

pdfFile=$1
shift
if [ $# -lt 2 ]
then
    echo "Usage:pdftool [filename] [discard pages]"
    exit
fi

pagesConserved=$(generateRanges $(getCouples $*))
pdftk_command=$(echo pdftk $pdfFile cat $pagesConserved output new_$(basename ${pdfFile}))
#echo $pdftk_command
$pdftk_command

根据大佬指点,使用bash自身的字符串展开替代cut命令:

#!/bin/bash
# 对pdftk的简单封装,用于删除指定的页码,以空格分隔,支持形如"5-7"的页码范围。页码输入不必按顺序,类似"12 6-8 1 3"输入是可以正常工作的。

#isPdftkinstalled作用为检查pdftk是否可用,若可用则执行pdftk --version
function isPdftkinstalled {
    echo
    if [ -z $(whereis pdftk | gawk '{print $2}') ]
    then
        echo "pdftk未安装或未加入PATH,请检查。"
        echo "提示:pdftk已加入Deepin官方源,您可以通过 sudo apt install pdftk 简单安装。"
    else
        echo $(pdftk --version)
    fi
    echo
}

#getCouples作用为对输入的页码进行处理,支持输入单页或页码范围,将其转换为数对(获取范围前后页码,以冒号分隔)
function getCouples {
    local couples=''
    local left_end=''
    local right_end=''
    while [ -n "$1" ]
    do      
        arg1=$(echo "$1" | gawk -F"[- ]" '{print $1}')
        arg2=$(echo "$1" | gawk -F"[- ]" '{print $2}')
        left_end=$[ $arg1 - 1 ]
        #对应页码范围情况
        if [ -n "$arg2" ]
        then
            right_end=$[ $arg2 + 1 ]
        else
        #对应单页情况
            right_end=$[ $arg1 + 1 ]
        fi
        couples=$(echo $couples $left_end:$right_end)
        shift
    done
    #数对排序处理,注意sort是针对行的排序,故需要将空格转换成换行
    couples=$(echo $couples | tr " " "\n" | sort -t ':' -k 1 -n)
    couples=$(refineCouples $couples)
    echo $couples
}

#refineCouples作用为合并相邻数对,供getCouples调用
function refineCouples {
    local args=''
    local isNabour=''
    #local Num1=$(echo $1 | cut -d ":" -f1)
    #local Num2=$(echo $1 | cut -d ":" -f2)
    local Num1=${1%%:*}
    local Num2=${1##*:}
    local Num3=''
    local Num4=''
    shift
    while [ -n "$1" ]
    do
        Num3=${1%%:*}
        Num4=${1##*:}
        isNabour=$[ $Num2 - $Num3 ]
        if [ $isNabour -eq 1 ]
        then
            Num2=$Num4
        else
            args=$(echo $args $Num1:$Num2)
            Num1=$Num3
            Num2=$Num4
        fi
        shift
    done
    args=$(echo $args $Num1:$Num2)
    echo $args
}

#generateRanges作用为将数对转换为pdftk可用的页码范围
function generateRanges {
    local first_Bit=${1%%:*}
    local Num1=''
    local Num2=''
    local args=''
    while [ -n "$1" ]
    do
        Num1=${1##*:}
        if [ -n "$2" ]
        then
            Num2=${2%%:*}
            if [ $Num1 -gt $Num2 ]
            then
                Num2=$Num1
            fi
        else
            Num2="end"
        fi
        shift
        args=$(echo $args $Num1-$Num2)
    done

    if [ $first_Bit -gt 0 ]
    then
        args=$(echo 1-$first_Bit $args)
    fi
    echo $args
}

pdfFile=$1
shift
if [ $# -lt 2 ]
then
    echo "Usage:pdftool [filename] [discard pages]"
    exit
fi

pagesConserved=$(generateRanges $(getCouples $*))
pdftk_command=$(echo pdftk $pdfFile cat $pagesConserved output new_$(basename ${pdfFile}))
#echo $pdftk_command
pdftk_command

可见使用bash本身的字符串替换更加高效灵活,通过#或%的数量可以制定首次匹配或最长匹配,用来截取文件名或后缀很有用。

bash递归函数测试

#!/bin/bash
# using recursion

function factorial {
    if [ $1 -lt 1 ]
    then
        echo 0
    elif [ $1 -eq 1 ]
    then
        echo 1
    else
        local temp1=$1
        local temp2=$(factorial $[ $1 - 1 ])
        local result=$[ $temp1 * $temp2 ]
        echo $result
    fi
}

function sumn {
    if [ $1 -lt 1 ]
    then
        echo 0
    elif [ $1 -eq 1 ]
    then
        echo 1
    else
        local temp1=$1
        local temp2=$(sumn $[ $1 - 1 ])
        local result=$[ $temp1 + $temp2 ]
        echo $result
    fi
}

function fbnq {
    if [ $1 -lt 1 ]
    then
        echo 0
    elif [ $1 -lt 2 ]
    then
        echo 1
    else
        local temp1=$(fbnq $[ $1 - 1 ])
        local temp2=$(fbnq $[ $1 - 2 ])
        local result=$[ $temp1 + $temp2 ]
        echo $result
    fi
}

read -p "Enter value: " value
result=$(factorial $value)
totalsum=$(sumn $value)
fibon=$(fbnq $value)
echo "The factorial of $value is: $result"
echo "The total sum of $value is: $totalsum"
echo "FibonacciRecursive of $value is: $fibon"

递归实现只有2步:构造递归表达式以及设定初值。

bash中简单函数数组传递

#!/bin/bash
# array variable to function test
function testit {
local newarray
newarray="$@"
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}

书中使用命令展开进行传值

newarray=($(echo "$@"))

经过试验,这种方式也可以:

newarray=("$@")

从输出来看一致,不过内在是否存在区别?

我自己来解答:

  1. newarray="$@" : newarray不是数组;
  2. newarray=("$@") : newarray是数组(套了圆括号)
  3. newarray=("$*") : newarray不是数组

对于第3点可以回顾一下$@$*的区别。$@中每个元素是独立的,$*只有一个元素。另外无论newarray是否为数组,${newarray[*]}都可以完整输出内容,因为当newarray不是数组的情况下,全部内容都在${newarray[0]}中,从标准输出来看没区别。

对于for而言数组与否没区别,它只会根据当前IFS分割元素。

再次回顾书中的方式:

newarray=($(echo "$@"))

这种方式看似愚笨,实则非常鲁棒。通过命令展开将不确定的输入类型输出成普通字符串,再套括号变成数组,值得品味。

bash中简单的bc计算

#!/bin/bash

var1=3.14
var2=5.2

var3=$(bc << EOF
scale = 4
a1 = $var1 + $var2
a2 = $var1 * $var2
a1 + a2
EOF
)

echo The final result is $var3

结果毫无悬念,24.668。注意这里用到了here document语法,行内重定向的一大用途便是方便在行间传递参数调用程序,通常搭配命令替换使用。另外注意,bc中引用外部变量(bash变量)时需要加$,bc中声明的变量是不需要的。

bash中简单的for循环

#!/bin/bash for_test.sh
sum=0
i=$(echo {1..5})
echo "The content of list:$i"
for var in $i
do
    echo "The current value is:$var"
    sum=$[$sum+$var]
    echo "The sum is: $sum"
done
echo "The final sum is: $sum"

感觉bash更适合编程入门,足够简单,少量知识就可以写出实用脚本实现对系统的自动化管理。许多“现代”语言虽然语法看起来“简单”,但是隐藏了许多细节,初学者到头来只会机械地调用模块,对于实际发生了什么毫无头绪,反而容易迷失方向。