Skip to main content

45 posts tagged with "linux"

View All Tags

· 2 min read

户名为 pi ,密码为 raspberry ssh root@10.15.202.200

官网 https://www.raspberrypi.org/

download https://alpinelinux.org/downloads

Raspberry Pi OS (previously called Raspbian) Win32DiskImager 硬盘 FAT32 电源 5v 3A

config

sudo raspi-config

windows远程访问的实现

apt-get install xrdp

https://www.instructables.com/id/Install-Alpine-Linux-on-Raspberry-Pi/

wpa_supplicant.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
ap_scan=1
fast_reauth=1
country=CN
network={
ssid="WIFI名称"
psk="WIFI密码"
priority=100
}

repo

https://mirror.tuna.tsinghua.edu.cn/help/raspbian/

buster

vi /etc/apt/sources.list deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib rpi deb http://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os/raspbian/ buster main non-free contrib rpi deb-src http://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os/raspbian/ buster main non-free contrib rpi

/etc/apt/sources.list.d/raspi.list deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui

sudo apt-get update

必装

sudo apt install -y vim tree

视频 usb motion

sudo apt install motion sudo motion http://localhost:8081

开机启动

sudo vi /etc/default/motion
#no修改成yes:
start_motion_daemon=yes

remote

sudo vi /etc/motion/motion.conf
# deamon off 改成 on
deamon on
# 设置分辨率
width 800
height 600
# 刷新率
framerate 30
streame_maxrate 30
# 关闭 localhost 的限制
stream_localhost off
webcontrol_localhost off

samba win+linux 文件共享

MJPGStreamer进行实时监控(USB摄像头篇)https://www.bilibili.com/video/BV1bt411c7fC?p=35

sudo apt-get install -y subversion
sudo apt-get install -y libjpeg8-dev
sudo apt-get install -y imagemagick
sudo apt-get install -y libv4l-dev
sudo apt-get install -y cmake
sudo git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
sudo make all
sudo make install
./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"
./mjpg_streamer -i "./input_uvc.so -f 30 -r 800x600" -o "./output_http.so -w ./www"
http://192.168.100.39:8080/stream.html

· One min read
click.py
import cv2


def draw_rectangle(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONDOWN:
print(x, y)
cv2.circle(img, center=(x, y), radius=5, color=(87, 184, 237), thickness=-1)
elif event == cv2.EVENT_LBUTTONUP:
cv2.circle(img, center=(x, y), radius=10, color=(87, 184, 237), thickness=1)


img = cv2.imread("./road-line.jpeg")

cv2.namedWindow(winname="my_drawing")
cv2.setMouseCallback("my_drawing", draw_rectangle)

# Step 3. Execution
while True:
cv2.imshow("my_drawing", img)
if cv2.waitKey(10) & 0xFF == 27:
break

cv2.destroyAllWindows()
trend.py
import cv2
import numpy as np

print(np.pi / 180)

img = cv2.imread("trend.png")
height = img.shape[0] # 高度
width = img.shape[1] # 宽度
cut_img = img

gray = cv2.cvtColor(cut_img, cv2.COLOR_BGR2GRAY)
cv2.waitKey(0)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

result = cut_img.copy()
minLineLength = 30 # height/32
maxLineGap = 10 # height/40
lines = cv2.HoughLinesP(edges, 1, np.pi / 1, 80, 0, 0)

for line in lines:
# for x1, y1, x2, y2 in lines[0]:
for x1, y1, x2, y2 in line:
if int(y2) != int(y1):
cv2.line(result, (x1, y1), (x2, y2), (0, 255, 0), 2)
else:
...

cv2.imshow("result", result)
cv2.waitKey(0)

· One min read

# 所有的 service
systemctl list-units --type=service

# 看日志
journalctl -u k3s -f

service nginx status
service nginx start
service nginx restart
service nginx stop

file list

cd /usr/lib/systemd/system
cd /etc/systemd/system/

k3s.service demo

[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
'--docker' \

· One min read

doc

install

https://www.terraform.io/downloads.html

wget https://releases.hashicorp.com/terraform/0.12.18/terraform_0.12.18_linux_amd64.zip
unzip terraform_0.12.18_linux_amd64.zip -d .
mv terraform /usr/bin/

cache

export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache" # windows is must
~/.terraform.rc

tee ~/.terraformrc <<-'EOF'
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true
EOF

cmd

  • terraform init
  • terraform apply -target=docker_container.mysql-1
provider "docker" {
default = "unix:///var/run/docker.sock"
# default = "tcp://127.0.0.1:2375"
}

variable "edf" {
default = "qqqq"
}

resource "docker_container" "ptest" {
name = "ptest"
image = "ptest"
ports {
internal = 5000
external = 2222
}
provisioner "local-exec" {
command = "echo ${var.password}"
}
}

resource "docker_container" "mysql-1" {
restart = "unless-stopped"
name = "mysql-1"
image = "mysql:8.0.15"
command = [
"--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci",
]
env = [
"MYSQL_ROOT_PASSWORD=${var.password}",
"TZ=Asia/Shanghai",
]
ports {
internal = 3306
external = 3306
}
}

· 11 min read

doc https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/lsof.html

lsof

https://mp.weixin.qq.com/s/IV-JZw6WZoaJPVN4AJrkOw

目标

前言

我们都知道,在linux下,“一切皆文件”,因此有时候查看文件的打开情况,就显得格外重要,而这里有一个命令能够在这件事上很好的帮助我们-它就是lsof。

linux下有哪些文件

在介绍lsof命令之前,先简单说一下,linux主要有哪些文件:

  • 普通文件
  • 目录
  • 符号链接
  • 面向块的设备文件
  • 面向字符的设备文件
  • 管道和命名管道
  • 套接字

以上各类文件类型不多做详细介绍。

lsof命令实用用法介绍

lsof,是list open files的简称。它的参数很多,但是我们这里只介绍一些实用的用法(注意有些情况需要root权限执行)。

查看当前打开的所有文件

一般来说,直接输入lsof命令产生的结果实在是太多,可能很难找到我们需要的信息。不过借此说明一下一条记录都有哪些信息。

`$ lsof(这里选取一条记录显示)  
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
vi 27940 hyb 7u REG 8,15 16384 137573 /home/hyb/.1.txt.swp`

lsof显示的结果,从左往右分别代表:打开该文件的程序名,进程id,用户,文件描述符,文件类型,设备,大小,iNode号,文件名。

我们暂且先关注我们知道的列。这条记录,表明进程id为27940的vi程序,打开了文件描述值为7,且处于读写状态的,在/home/hyb目录下的普通文件( REG regular file).1.txt.swap,当前大小16384字节。

列出被删除但占用空间的文件

在生产环境中,我们可能会使用df命令看到磁盘空间占满了,然而实际上又很难找到占满空间的文件,这常常是由于某个大文件被删除了,但是它却被某个进程打开,导致通过普通的方式找不到它的踪迹,最常见的就是日志文件。我们可以通过lsof来发现这样的文件:

`$ lsof |grep deleted  
Xorg 1131 root 125u REG 0,5 4 61026 /memfd:xshmfence (deleted)
Xorg 1131 root 126u REG 0,5 4 62913 /memfd:xshmfence (deleted)
Xorg 1131 root 129u REG 0,5 4 74609 /memfd:xshmfence (deleted)`

可以看到这些被删除的但仍然被打开文件,最后查找出来的时候,会被标记deleted。这个时候就可以根据实际情况分析,到底哪些文件可能过大但是却被删除了,导致空间仍然占满。

恢复打开但被删除的文件

前面我们可以找到被删除但是仍然被打开的文件,实际上文件并没有真正的消失,如果是意外被删除的,我们还有手段恢复它。以/var/log/syslog文件为例,我们先删除它( root用户):

`$ rm /var/log/syslog`

然后使用lsof查看那个进程打开了该文件:

`$ lsof |grep syslog  
rs:main 993 1119 syslog 5w REG 8,10 78419 528470 /var/log/syslog (deleted)`

可以找到进程id为993的进程打开了该文件,我们知道每个进程在/proc下都有文件描述符打开的记录:

`$ ls -l /proc/993/fd  
lr-x------ 1 root root 64 3月 5 18:30 0 -> /dev/null
l-wx------ 1 root root 64 3月 5 18:30 1 -> /dev/null
l-wx------ 1 root root 64 3月 5 18:30 2 -> /dev/null
lrwx------ 1 root root 64 3月 5 18:30 3 -> socket:[15032]
lr-x------ 1 root root 64 3月 5 18:30 4 -> /proc/kmsg
l-wx------ 1 root root 64 3月 5 18:30 5 -> /var/log/syslog (deleted)
l-wx------ 1 root root 64 3月 5 18:30 6 -> /var/log/auth.log`

这里就找到了被删除的syslog文件,文件描述符是5,我们把它重定向出来:

`$ cat /proc/993/fd/5 > syslog  
$ ls -al /var/log/syslog
-rw-r--r-- 1 root root 78493 3月 5 19:22 /var/log/syslog`

这样我们就恢复了syslog文件。

查看当前文件被哪些进程打开

Windows下经常遇到要删除某个文件,然后告诉你某个程序正在使用,然而不告诉你具体是哪个程序。我们可以在资源管理器-性能-资源监视器-cpu-关联的句柄处搜索文件,即可找到打开该文件的程序,但是搜索速度感人。

linux就比较容易了,使用lsof命令就可以了,例如要查看当前哪些程序打开了hello.c:

`$ lsof hello.c  
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tail 28731 hyb 3r REG 8,15 228 138441 hello.c`

但是我们会发现,使用vi打开的hello.c并没有找出来,这是因为vi打开的是一个临时副本。我们换一种方式查找:

`$ lsof |grep hello.c  
tail 28906 hyb 3r REG 8,15 228 138441 /home/hyb/workspaces/c/hello.c
vi 28933 hyb 9u REG 8,15 12288 137573 /home/hyb/workspaces/c/.hello.c.swp`

这样我们就找到了两个程序和hello.c文件相关。

这里grep的作用是从所有结果中只列出符合条件的结果。

查看某个目录文件被打开情况

`$ lsof +D ./`

查看当前进程打开了哪些文件

使用方法:lsof -c 进程名
通常用于程序定位问题,例如用于查看当前进程使用了哪些库,打开了哪些文件等等。假设有一个循环打印字符的hello程序:

`$ lsof -c hello  
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
hello 29190 hyb cwd DIR 8,15 4096 134538 /home/hyb/workspaces/c
hello 29190 hyb rtd DIR 8,10 4096 2 /
hello 29190 hyb txt REG 8,15 9816 138314 /home/hyb/workspaces/c/hello
hello 29190 hyb mem REG 8,10 1868984 939763 /lib/x86_64-linux-gnu/libc-2.23.so
hello 29190 hyb mem REG 8,10 162632 926913 /lib/x86_64-linux-gnu/ld-2.23.so
hello 29190 hyb 0u CHR 136,20 0t0 23 /dev/pts/20
hello 29190 hyb 1u CHR 136,20 0t0 23 /dev/pts/20
hello 29190 hyb 2u CHR 136,20 0t0 23 /dev/pts/20`

我们可以从中看到,至少它用到了/lib/x86_64-linux-gnu/libc-2.23.so以及hello文件。

也可以通过进程id查看,可跟多个进程id,使用逗号隔开:

`$ lsof -p 29190  
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
hello 29190 hyb cwd DIR 8,15 4096 134538 /home/hyb/workspaces/c
hello 29190 hyb rtd DIR 8,10 4096 2 /
hello 29190 hyb txt REG 8,15 9816 138314 /home/hyb/workspaces/c/hello
hello 29190 hyb mem REG 8,10 1868984 939763 /lib/x86_64-linux-gnu/libc-2.23.so
hello 29190 hyb mem REG 8,10 162632 926913 /lib/x86_64-linux-gnu/ld-2.23.so
hello 29190 hyb 0u CHR 136,20 0t0 23 /dev/pts/20
hello 29190 hyb 1u CHR 136,20 0t0 23 /dev/pts/20
hello 29190 hyb 2u CHR 136,20 0t0 23 /dev/pts/20`

当然这里还有一种方式,就是利用proc文件系统,首先找到hello进程的进程id
:

`$ ps -ef|grep hello  
hyb 29190 27929 0 21:14 pts/20 00:00:00 ./hello 2
hyb 29296 28848 0 21:18 pts/22 00:00:00 grep --color=auto hello`

可以看到进程id为29190,查看该进程文件描述记录目录:

`$ ls -l /proc/29190/fd  
lrwx------ 1 hyb hyb 64 3月 2 21:14 0 -> /dev/pts/20
lrwx------ 1 hyb hyb 64 3月 2 21:14 1 -> /dev/pts/20
lrwx------ 1 hyb hyb 64 3月 2 21:14 2 -> /dev/pts/20`

这种方式能够过滤很多信息,因为它只列出了该进程实际打开的,这里它只打开了0,1,2,即标准输入,标准输出和标准错误。

查看某个端口被占用情况

在使用数据库或者启用web服务的时候,总能遇到端口占用问题,那么怎么查看某个端口是否被占用呢?

`$ lsof -i :6379  
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 29389 hyb 6u IPv6 534612 0t0 TCP *:6379 (LISTEN)
redis-ser 29389 hyb 7u IPv4 534613 0t0 TCP *:6379 (LISTEN)`

这里可以看到redis-ser进程占用了6379端口。

查看所有的TCP/UDP连接

`$ lsof -i tcp  
ava 2534 hyb 6u IPv6 31275 0t0 TCP localhost:9614 (LISTEN)
java 2534 hyb 22u IPv6 96922 0t0 TCP localhost:9614->localhost:39004 (ESTABLISHED)
java 2534 hyb 23u IPv6 249588 0t0 TCP localhost:9614->localhost:45460 (ESTABLISHED)`

当然我们也可以使用netstat命令。

`$ netstat -anp|grep 6379`

这里的-i参数可以跟多种条件:

  • -i 4 #ipv4地址
  • -i 6 #ipv6地址
  • -i tcp #tcp连接
  • -i :3306 #端口
  • -i @ip #ip地址

因此需要查看与某个ip地址建立的连接时,可以使用下面的方式:

`$ lsof -i@127.0.0.1`

查看某个用户打开了哪些文件

linux是一个多用户操作系统,怎么知道其他普通用户打开了哪些文件呢?可使用-u参数

`$ lsof -u hyb  
(内容太多,省略)`

列出除了某个进程或某个用户打开的文件

实际上和前面使用方法类似,只不过,在进程id前面或者用户名前面加^,例如:

`lsof -p ^1     #列出除进程id为1的进程以外打开的文件  
lsof -u ^root #列出除root用户以外打开的文件`

总结

以上介绍基于一个条件,实际上多个条件可以组合,例如列出进程id为1的进程打开的tcp套接字文件:

`lsof -p 1 -i tcp`

lsof参数很多,具体的可以使用man命令查看,但是对于我们来说,知道这些实用的基本足够。 去除 iconfinder 上 icon 的水印

原理

利用水印像素点和原图像素点颜色合并的原理,如果拥有加过水印的图片和水印图片,就可以反向推出原图原像素点的颜色;前提是你得拥有他的水印图片

· One min read

jenkins

Docker持续部署图文详解 http://www.csdn.net/article/2015-07-21/2825266 使用Docker构建持续集成与自动部署的Docker集 https://my.oschina.net/jayqqaa12/blog/633683

install

mkdir jk && cd jk
# 注意是当前user
docker run --restart=unless-stopped --name jenkins -it -d \
--privileged=true \
-u root \
-p 8080:8080 -p 50000:50000 \
-v "$PWD":/var/jenkins_home jenkins:2.60.3

proxy

jenkins->系统管理->管理插件->高级 把:http://updates.jenkins-ci.org/update-center.json 换成:http://mirror.esuni.jp/jenkins/updates/update-center.json

时区问题

【系统管理】->【脚本命令行】运行下面的命令 System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')

· 2 min read
yum -y install bind bind-utils

service named start

vi /etc/named.conf 修改any

service named restart

netstat -antlpe | grep named

# 验证配置文件是否有错误
named-checkzone test.com /var/named/test.com.zone

本地配置 dns

vi /etc/resolv.conf

# Generated by NetworkManager
nameserver 172.16.30.28
nameserver 202.96.202.5
nameserver 114.114.114.114

cd /var/named/ cp -p named.localhost named.inner

demo hk.com

$TTL 1D
@ IN SOA dns.hk.com. root.hk.com. (
0 ; serial
1H ; refresh
1H ; retry
1H ; expire
1H ) ; minimum
NS dns.hk.com.
dns A 172.16.30.11
www A 172.16.30.22
news A 172.16.30.33

vi /var/named/named.inner

$TTL 1D
@ IN SOA @ root.inner.test.tianshengcm.com. (
0 ; serial
1H ; refresh
1H ; retry
1H ; expire
1H ) ; minimum
IN NS @
IN A 172.16.30.28
@ IN A 172.16.30.28
ynh-app IN A 172.16.30.28
ynh-rcm IN A 172.16.30.28
ynh-cs IN A 172.16.30.28
fhh-app IN A 172.16.30.28
fhh-rcm IN A 172.16.30.28
fhh-cs IN A 172.16.30.28
* IN A 172.16.30.28

追加 vi /etc/named.rfc1912.zones

zone "hk.com" IN {
type master;
file "hk.com";
allow-update { none; };
};
zone "inner.test.tianshengcm.com" IN {
type master;
file "named.inner";
allow-update { none; };
};

dig inner.test.tianshengcm.com

· One min read

rabbitmq

docker pull rabbitmq:3.7.8

docker run -d --name rabbitmq-1 rabbitmq:3.7.8

docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4368:4368 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:3.7.8-management
http://0.0.0.0:15672
guest/guest

demo

<?php

namespace app\console\controllers;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use yii\console\Controller;

class QueueController extends Controller
{

public function actionIn($n = 1)
{
$connection = new AMQPStreamConnection('172.16.30.123', 5672, 'guest', 'guest');
$channel = $connection->channel();

// if not exist
$channel->queue_declare('hello', false, false, false, false);

$msg = 'hello_' . date('H_i_s');
$msg = new AMQPMessage($msg);
$channel->basic_publish($msg, '', 'hello');

echo "Send: {$msg->body}\n";
$channel->close();
$connection->close();
}

public function actionExec()
{
$connection = new AMQPStreamConnection('172.16.30.123', 5672, 'guest', 'guest');
$channel = $connection->channel();

// if not exist
$channel->queue_declare('hello', false, false, false, false);

echo "Start\n";
$callback = function ($msg) use ($channel) {
/** @var AMQPMessage $msg */
echo "Get: {$msg->body}\n";

// ack
$delivery_tag = $msg->delivery_info['delivery_tag'];
$channel->basic_ack($delivery_tag);
};

$channel->basic_consume('hello', '', false, false, false, false, $callback);

while (count($channel->callbacks)) {
$channel->wait();
}
}

}