• [技术干货] Linux启动过程以及7种运行级别
    Linux启动过程Linux启动需要经历一些步骤,这些步骤确保系统能够在各种不同的硬件和配置条件下可靠地启动和运行,并且具有足够的灵活性以适应不同的使用场景和需求,具体步骤如下:BIOS/UEFI初始化(硬件初始化):执行基本输入输出系统(BIOS)或统一可扩展接口(UEFI)中的初始化程序。这些程序负责硬件的自检、加载引导程序等操作,这确保了系统能够正确地与硬件交互,并且提供了基本的硬件支持。引导加载程序(Boot Loader):BIOS/UEFI初始化后,控制权被传递给引导加载程序,从而加载操作系统的内核映像和必要的初始化RAM磁盘映像,以及传递启动参数给内核;这个过程是系统启动的关键一步,确保了正确的内核被加载并且系统启动参数被正确传递。Linux内核启动:引导加载程序将控制权交给Linux内核。内核启动时,会初始化硬件、加载必要的驱动程序以及创建第一个用户进程(init进程);这确保了系统能够正确地与硬件交互,并且能够访问存储在磁盘上的文件系统。init进程启动:init 进程是 Linux 系统的第一个用户空间进程,它负责启动系统的其他进程和服务;通过 init 进程,系统可以在启动时根据需要启动不同的服务,并且提供了系统运行级别的管理和切换功能。运行级别初始化:根据系统的默认运行级别,init 进程会启动相应的运行级别。每个运行级别都定义了一组需要启动的系统服务和进程。通过运行级别,管理员可以根据需要轻松地切换系统的运行状态,并且可以根据需要启动或停止不同的服务。系统初始化和用户登录:一旦系统处于适当的运行级别并启动了所需的服务,系统就会初始化各种设置和环境。如果是多用户环境,系统会等待用户登录。登录后,用户可以开始使用系统。Linux中的7种运行级别通过设置不同的运行级别,管理员可以实现系统启动时的自定义配置,例如启用或禁用特定服务、加载特定的内核模块等。这种灵活性使得 Linux 系统可以更好地适应不同的使用场景和需求。单用户模式(runlevel 1):也称为救援模式,系统在此模式下只启动最基本的服务和进程,通常用于系统修复和维护。多用户模式(runlevel 2、3、4):这些运行级别通常用于多用户环境下,系统启动基本的网络服务,但不包含图形用户界面。多用户图形界面模式(runlevel 5):系统启动图形用户界面和相关服务,适用于桌面系统或需要图形界面的服务器环境。关机(runlevel 0):系统关闭所有服务并停止运行;重新启动(runlevel 6):系统重新启动;与运行级别相关的 Bash 指令通常用于管理系统的运行级别以及执行与运行级别相关的操作。以下是一些常用的与运行级别相关的 Bash 指令:runlevel #显示当前系统的运行级别 telinit <运行级别> #用于改变系统的运行级别 init <运行级别> #传统的系统初始化程序,也可用来改变系统的运行级别 chkconfig --list # 显示所有系统服务及其在各个运行级别下的启用情况 chkconfig <服务名> on # 将指定服务在启动时自动启用 chkconfig <服务名> off # 将指定服务在启动时取消自动启用
  • [技术干货] CentOS上搭建SFTP
    在CentOS上安装SFTP服务通常是通过安装OpenSSH来实现的,因为OpenSSH默认提供了SFTP功能。以下是在CentOS上安装SFTP的步骤:一、安装OpenSSH服务器:sudo yum install openssh-server启动SSH服务:sudo systemctl start sshd确保SSH服务随系统启动而启动:sudo systemctl enable sshd检查SSH服务状态:sudo systemctl status sshd这将显示SSH服务是否正在运行以及其他相关信息。现在,你的CentOS服务器上应该已经安装并运行了SFTP服务。你可以使用任何支持SFTP的客户端(如WinSCP、FileZilla等)连接到服务器。确保使用SSH协议(端口22)进行连接,并使用具有适当权限的用户凭据进行身份验证。二、配置sftp用户、访问目录等下面是一个完整的例子,假设我们要创建一个名为sftpuser的用户,限制他只能访问/sftp目录,并且使用特定的SSH配置文件。创建SFTP用户:sudo useradd -m -s /sbin/nologin sftpuser设置用户密码:sudo passwd sftpuser创建用户的SFTP根目录:sudo mkdir /sftp设置根目录的权限(根目录必须是root用户,否则sftp连接不上):sudo chown root:root /sftpsudo chmod 755 /sftp在根目录下层建立子目录方可以写入(根目录只能读取不能写入,因为根目录必须是root用户,而sftp访问的用户却是我们新建的sftpuser)mkdir /sftp/sharedatachown sftpuser:sftpuser /sftp/sharedata创建新用户自定义ssh配置简单点直接修改/etc/ssh/sshd_config也可以,这样服务启动选项sshd.service就不用改了创建用户的SSH配置文件目录:sudo mkdir /home/sftpuser/.ssh复制系统SSH配置文件到用户目录:sudo cp /etc/ssh/sshd_config /home/sftpuser/.ssh/sshd_config编辑用户的SSH配置文件:sudo vi /home/sftpuser/.ssh/sshd_config在这个文件中,确保你有适当的配置,例如使用ChrootDirectory限制用户访问,以及其他任何你想要自定义的配置。注意将这个配置节放到最后,否则老是报错: "Directive 'UseDNS' is not allowed within a Match block" 表明在 Match 块中不允许使用 UseDNS 这个指令。Match User sftpuser    ChrootDirectory /sftp    ForceCommand internal-sftp    AllowTcpForwarding noX11Forwarding no给新用户的用户目录递归设置归属chown -R sftpuser:sftpuser /home/sftpuser给配置文件设置读取权限chmod 755 /home/sftpuser/.ssh/sshd_config修改SSH服务启动选项打开SSH服务的启动选项文件,可以使用systemctl status sshd查看找到(通常在 /etc/systemd/system/sshd.service 或 /etc/init.d/sshd 或/usr/lib/systemd/system/sshd.service),并修改为:ExecStart=/usr/sbin/sshd -f /home/sftpuser/.ssh/sshd_config -D $OPTIONS或者/usr/sbin/sshd -f /home/sftpuser/.ssh/sshd_config $OPTIONS重新加载SSH服务:systemctl daemon-reloadsystemctl restart sshd现在,用户sftpuser被限制在sftp目录下,并且只能使用SFTP进行文件传输。他们的SSH配置文件位于/home/sftpuser/.ssh/sshd_config,这样他们可以自定义他们的SSH行为而不影响其他用户或系统级别的配置。查看错误日志:检查系统日志:如果问题仍然存在,请查看系统日志文件,如 /var/log/auth.log 或 /var/log/secure,以获取有关写入文件失败的详细信息。日志文件中可能会提供关于出现问题的原因的线索。三、多SFTP用户如何配置SSH服务启动选项只能指定一个配置文件。如果你想要为多个用户指定不同的配置,你需要为每个用户创建单独的配置文件,并在启动选项中指定这些文件。例如,如果你有两个用户 sftpuser1 和 sftpuser2,你可以为他们分别创建不同的配置文件,然后在SSH服务的启动选项中指定这些文件。为每个用户创建配置文件:sudo cp /etc/ssh/sshd_config /home/sftpuser1/.ssh/sshd_configsudo cp /etc/ssh/sshd_config /home/sftpuser2/.ssh/sshd_config编辑每个用户的配置文件并根据需要进行自定义:sudo vi /home/sftpuser1/.ssh/sshd_configMatch User sftpuser1    ChrootDirectory /sftp    ForceCommand internal-sftp    AllowTcpForwarding no    X11Forwarding nosudo vi /home/sftpuser2/.ssh/sshd_configMatch User sftpuser2    ChrootDirectory /sftp/other_directory    ForceCommand internal-sftp    AllowTcpForwarding no    X11Forwarding no修改SSH服务的启动选项,分别指定每个用户的配置文件:ExecStart=/usr/sbin/sshd -f /home/sftpuser1/.ssh/sshd_config -f /home/sftpuser2/.ssh/sshd_config -D $OPTIONS或者/usr/sbin/sshd -f /home/sftpuser1/.ssh/sshd_config -f /home/sftpuser2/.ssh/sshd_config $OPTIONS这样配置后,每个用户将使用自己的配置文件,可以分别定制他们的SSH行为。
  • [技术干货] docker 修改运行容器环境变量
    第一步:查看Docker Root目录docker info | grep 'Docker Root'第二步:查到容器的长id(container id)方式一:docker inspect pdmaas | grep "Id"方式二:docker ps -a --no-trunc | grep pdmaas第三步:停止容器docker stop [容器名|容器id]第四步:编辑修改环境变量env建议:修改前先备份!!!vim ${Docker Root}/containers/${container-id}/config.v2.json 或 vim ${Docker Root}/containers/${container-id}/config.jsonjson文件代码是压缩的,可以使用sz path命令下载下来格式化后再编辑,再用rz -y命令上传覆盖第五步:重载服务的配置文件systemctl daemon-reload第六步:重启docker转载自https://www.cnblogs.com/bgyb/p/18191197systemctl restart docker
  • [技术干货] Nginx配置允许跨域
    要在Nginx中配置允许跨域(Cross-Origin Resource Sharing, CORS),你需要修改Nginx的配置文件(通常是nginx.conf或者某个包含在nginx.conf中的单独的配置文件)。下面是一个基本的例子,展示了如何在Nginx中设置CORS:打开你的Nginx配置文件。这通常是/etc/nginx/nginx.conf或者/etc/nginx/conf.d/default.conf,或者一个特定站点的配置文件在/etc/nginx/sites-available/或/etc/nginx/conf.d/目录下。在你想要允许跨域请求的server块或location块中添加add_header指令。下面是一个简单的例子,它允许来自任何源的跨域请求,并允许所有的请求方法(GET, POST, PUT, DELETE等)和请求头:server { listen 80; server_name your.domain.com; location / { # ... 其他的配置 ... # 允许跨域请求 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # 自定义的头部可能需要额外的配置 # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # 告诉客户端,实际请求可以预检,并返回一个非简单请求的预检结果且缓存该结果 # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST' || $request_method = 'GET' || $request_method = 'PUT' || $request_method = 'DELETE') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # 如果需要处理跨域Cookie,请取消下面的注释 # # add_header 'Access-Control-Allow-Credentials' 'true'; } # ... 其他的代理或静态文件配置 ... } }注意:* 允许来自任何源的请求,但在生产环境中,出于安全考虑,你应该明确指定允许的源。如果你需要处理跨域Cookie(即withCredentials设置为true的XHR/Fetch请求),则必须设置Access-Control-Allow-Credentials为true,并且Access-Control-Allow-Origin不能设置为*,而应该是一个具体的源(如http://example.com)。在处理OPTIONS预检请求时,Nginx直接返回204状态码,这告诉浏览器请求是允许的,并且不需要实际发送请求体。请根据你的实际需求调整允许的HTTP方法和请求头。修改完Nginx配置文件后,重新加载或重启Nginx服务以使更改生效:sudo nginx -s reload # 或者 sudo systemctl reload nginx # 或者完全重启Nginx服务 sudo systemctl restart nginx本文来自博客园,作者:dashery,转载请注明原文链接:cid:link_0
  • [技术干货] 逻辑地址和物理地址及逻辑磁盘和物理磁盘
    一、逻辑地址和物理地址1.1 含义:逻辑地址和物理地址是计算机内存管理中的两个核心概念,它们在计算机系统中扮演着不同的角色。逻辑地址(Logical Address),也称为虚拟地址(Virtual Address),是由操作系统提供给程序使用的地址。这些地址是在程序中使用的,但并不是实际存在的地址。逻辑地址的大小和位数取决与处理器的架构和操作系统的设计,通常是一个定长的二进制数值。在执行指令时,CPU会将逻辑地址转换未物理地址来取数据。物理地址(Physical Address),是指内存中实际的地址,他表示内存模块中每个存储的单元(通常是字节)的唯一标识符,因此具有唯一性,且直接与内存相关联。物理地址通常是以一个十六进制表示的数字,他确定了计算机中的实际内存位置。总结来说,逻辑地址是虚拟的,而物理地址是实际的。逻辑地址是程序中使用的地址,它需要经过转换后才能访问到实际的物理地址。在内存管理中,操作系统根据自己的算法将逻辑地址转换为物理地址,使得程序能够正常地读取和写入内存中的数据。逻辑地址与物理地址之间存在着映射关系,但它们并不相等,还需要经过地址映射的过程。Top二、逻辑磁盘和物理磁盘2.1含义逻辑磁盘和物理磁盘的关系可以通过LVM(Logical Volume Manager)系统来理解。在LVM中,物理存储设备如硬盘分区或整个硬盘被转换为物理卷(Physical Volume,简称PV),这些物理卷然后聚集形成卷组(Volume Group,简称VG)。在卷组之上,可以创建逻辑卷(Logical Volume,简称LV)。这些逻辑卷是标准的块设备,可以在其上建立文件系统,相当于非LVM系统中的分区。具体来说,物理卷对应的是硬件存储,是磁盘或者磁盘分区,是物理存在。而卷组和逻辑卷则是逻辑上的存在。逻辑卷是在卷组上建立的,可以根据业务需求扩展或收缩,提供更大的灵活性和管理便利。此外,逻辑磁盘也可以在逻辑上再次进行划分,例如,有多个物理磁盘通过RAID和技术组成一个虚拟磁盘后,还可以将这个虚拟磁盘划分为多个逻辑磁盘。这些逻辑磁盘可能并不一定位于同一块物理磁盘上,它们可能是跨多个物理磁盘的,这样可以提高I/O效率。
  • [技术干货] 使用tc命令模拟linux网络延迟环境
    tc(Traffic Control)是 Linux 中用于流量控制和网络模拟的强大工具。你可以使用它来模拟网络延迟、带宽限制、数据包丢失等。以下是一个使用 tc 模拟网络延迟的基本步骤:1.查看当前的 qdisc(队列规则)和 filter(过滤器)首先,确保你的网络接口没有设置任何 qdisc。你可以使用以下命令查看:tc qdisc show dev <interface>其中 <interface> 是你的网络接口名称,如 eth0。2. 设置根 qdisc为了应用 tc 规则,你需要在网络接口上设置一个 qdisc。最常用的 qdisc 是 handleroot,但在这里我们将使用 htb(层次化令牌桶)作为示例,因为它允许我们设置更复杂的规则(尽管对于简单的延迟模拟,这并不是必需的)。tc qdisc add dev <interface> root handle 1: htb3. 添加延迟规则现在,你可以添加一个延迟规则。假设你想为所有从 <interface> 发送的数据包添加 100ms 的延迟:tc qdisc add dev <interface> parent 1:1 netem delay 100ms注意:上面的命令中,1:1 是一个子 qdisc 的句柄。在 htb qdisc 下,我们通常使用这种子 qdisc 来应用特定的规则。但是,对于简单的延迟模拟,你也可以直接使用 root qdisc,即:tc qdisc change dev <interface> root netem delay 100ms4. 验证设置你可以使用 ping 或其他网络工具来验证延迟是否已应用。5. 删除规则当你完成模拟并希望删除这些规则时,可以使用以下命令:tc qdisc del dev <interface> root这将删除网络接口上的所有 qdisc 和相关的规则。6. 注意tc 规则在重启或网络接口重新加载后将失效。如果你希望这些规则在重启后仍然生效,你可能需要考虑将它们添加到启动脚本或 systemd 服务中。但是,请注意,这样做可能会影响生产环境的网络性能。始终在测试环境中验证你的更改。本文来自博客园,作者:dashery,转载请注明原文链接:cid:link_0
  • [技术干货] Centos7安装weblogic
    1、配置java环境weblogic运行依赖java环境,所以第一步先配置java环境上传、解压jdk安装包[root@bogon ~]# rz -be[root@bogon ~]# tar -zxvf jdk1.8.tar.gz配置java环境变量[root@bogon ~]# vim /etc/profileexport JAVA_HOME=/opt/jdk1.8export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/libexport PATH=$JAVA_HOME/bin:$PATH保存后执行刷新配置文件[root@bogon ~]# source /etc/profile查看jdk版本,有如下结果说明java环境配置成功[root@bogon ~]# java -versionjava version "1.8.0_231"Java(TM) SE Runtime Environment (build 1.8.0_231-b11)Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)2、新建用户、用户组weblogic[root@bogon ~]# groupadd weblogic[root@bogon ~]# useradd -g weblogic weblogic3、创建安装目录[root@bogon ~]# mkdir -pv /opt/weblogic/Install[root@bogon ~]# mkdir -pv /opt/weblogic/Oracle/Middleware[root@bogon ~]# chown weblogic.weblogic /opt/weblogic/install -R[root@bogon ~]# chown weblogic.weblogic /opt/weblogic/Oracle/Middleware -R4、在weblogic安装目录分别创建两个文件(wls.rsp oraInst.loc)[root@bogon ~]# cd /opt/weblogic/Install[root@bogon weblogic]# vim wls.rsp[ENGINE]Response File Version=1.0.0.0.0[GENERIC]ORACLE_HOME=/opt/weblogic/Oracle/MiddlewareINSTALL_TYPE=WebLogic ServerMYORACLESUPPORT_USERNAME=MYORACLESUPPORT_PASSWORD=DECLINE_SECURITY_UPDATES=tureSECURITY_UPDATES_VIA_MYORACLESUPPORT=falsePROXY_HOST=PROXY_PORT=PROXY_USER=PROXY_PWD=<SECURE VALUE>COLLECTOR_SUPPORTTHUB_URL=[root@bogon weblogic]# vim oraInst.locInventory_loc=/opt/weblogic/oraInventoryInst_group=weblogic注意:两个文件不能有中文注释和多余的空格5、上传、解压安装包上传安装包到/opt/weblogic/Install[root@bogon weblogic]# rz -be[root@bogon weblogic]# unzip fmw_14.1.1.0.0_wls_lite_quick_Disk1_1of1.zip6、安装weblogic[root@bogon weblogic]# su - weblogic[weblogic@bogon ~]$ cd /app/weblogic/Install[weblogic@bogon weblogic]$ java -jar fmw_14.1.1.0.0_wls_lite_quick_generic.jar -silent -responseFile /opt/weblogic/Install/wls.rsp -invPtrLoc /opt/weblogic/Install/oraInst.loc等待安装完成5-10分钟左右The installation of Oracle Fusion Middleware 12c WebLogic Server and Coherence 12.2.1.3.0 completed successfully.Logs successfully copied to /opt/weblogic/oraInventory/logs.[weblogic@bogon weblogic]$出现successfully即为安装完成7、创建Domain(域)需要切换root账户在此目录下创建至此文件夹mkdir -p 确保目录名称存在,不存在的就建一个 最好复制 不要创建错误[weblogic@bogon weblogic]$ su - root[root@bogon ~]# mkdir -p /opt/weblogic/Oracle/Middleware/user_projects/domains/base_domain/[root@bogon ~]# cd /opt/weblogic/Oracle/Middleware/wlserver/common/bin/ 注意:/opt/weblogic/Oracle/Middleware/如果没有wlserver目录,去/opt/weblogic/Install/下边找 或者直接将wlserver移动到/opt/weblogic/Oracle/Middleware/[root@bogon ~]# mv /opt/weblogic/Install/wlserver /opt/weblogic/Oracle/Middleware/8、执行wlst.sh文件[root@bogon bin]# sh wlst.sh注:稍等几分钟 会查找所有的jar文件,出现如下就可以进行下一步的操作Welcome to WebLogic Server Administration Scripting ShellType help() for help on available commandswls:/offline>依次执行以下:wls:/offline> readTemplateForUpdate('/opt/weblogic/Oracle/Middleware/wlserver/common/templates/wls/wls.jar')wls:/offline/base_domain> cd ('Server/AdminServer')wls:/offline/base_domain/Server/AdminServer> set('ListenAddress','')wls:/offline/base_domain/Server/AdminServer> set('ListenPort',7001) 设置访问端口 自定义 要把防火墙开放wls:/offline/base_domain/Server/AdminServer> cd('/')wls:/offline/base_domain> cd('Security/base_domain/User/weblogic')wls:/offline/base_domain/Security/base_domain/User/weblogic> cmo.setPassword('weblogic1234') 设置密码 至少英文加数字wls:/offline/base_domain/Security/base_domain/User/weblogic> setOption('OverwriteDomain','true')wls:/offline/base_domain/Security/base_domain/User/weblogic> writeDomain('/opt/weblogic/Oracle/Middleware/user_projects/domains/base_domain/') 写入领域 这个目录就是刚才创建的wls:/offline/base_domain/Security/base_domain/User/weblogic> closeTemplate()wls:/offline> exit()9、启动weblogic[root@bogon bin]# cd /opt/weblogic/Oracle/Middleware/user_projects/domains/base_domain[root@bogon bin]# ./startWeblogic.sh启动比较慢,启动后浏览器访问http://ip:7001/console访问前注意检查防火墙是否关闭10、编写启停管理脚本[root@bogon weblogic]# vim startAdmin.sh#!/bin/sh#export USER_MEM_ARGS="-Xms4096m -Xmx4096m -XX:MaxPermSize=512m"nohup sh /app/weblogic/Oracle/Middleware/user_projects/domains/base_domain/bin/startWebLogic.sh > admin.log 2>&1 &[root@bogon weblogic]# vim stopAdmin.sh#!/bin/shps -ef|grep Name=AdminServer |grep -v grep|head -n 1|awk '{print $2}'|xargs -t -i kill -9 {}欢迎各位同仁来提意见与建议!
  • [技术干货] Linux系统中如何查看磁盘情况
    Linux不像windows系统那样方便的图形界面,特别是作为服务器使用的时候,只有命令行可以使用。我有个云服务器平时用来做一些数据分享用的,最近想看看磁盘和其中文件的占用情况,于是搜索并学习了一些查看磁盘空间信息的命令,命令虽然简单,但对我自己来说还是有些新的东西值得记录。1. df首先,登录服务器用df命令查看磁盘情况:/home/projects/databook# df . Filesystem 1K-blocks Used Available Use% Mounted on /dev/vda1 51420828 14018512 35079240 29% / 输出包含当前文件系统的磁盘使用情况。df命令有个-h参数,可以更好的展示磁盘情况:/home/projects/databook# df -h . Filesystem Size Used Avail Use% Mounted on /dev/vda1 50G 14G 34G 29% /-h参数一般是用来显示帮助信息的,但是对于df命令,h表示human,也就是以人类易读的方式显示。上面的输出表示这个磁盘的使用量,包括我的虚拟服务器上的所有内容——可执行文件、库和支持文件等等。总容量 50G,目前只使用了29%,剩余的还比较充裕。2. du接下来,我想看看databook目录的文件占用情况。这需要使用 du 命令:/home/projects/databook# du -hd 1 . 24K ./certs 4.0K ./download 3.2M ./admin-ui 2.9M ./public 108K ./output 181M ./upload 472K ./markdown-files 207M . 同样,-h参数表示以人类易读的方式显示,-d 1参数表示 du 只进入一个目录级别(也就是当前目录)。从输出可以看出,upload目录稍微大点,其他目录都还好。最后一行 207M 是整个目录占用磁盘的大小。我希望按照文件/文件夹 占用磁盘空间大小的顺序来显示,这样可以快速定位到占用空间大的 文件/文件夹。3. du | sort但是,du命令并没有按磁盘空间排序的参数,所以尝试结合 sort 命令来排序。/home/projects/databook# du -hd 1 . | sort -n 2.9M ./public 3.2M ./admin-ui 4.0K ./download 24K ./certs 108K ./output 181M ./upload 207M . 472K ./markdown-filessort命令的-n参数表示按数字排序,不过文件夹大小不仅有数字,还有单位(比如M,K这些)。所以,这样排序对我们用处不大。接着,尝试所有文件统一用字节表示,然后在排序:/home/projects/databook# du -kd 1 . | sort -n 4 ./download 24 ./certs 108 ./output 472 ./markdown-files 2948 ./public 3224 ./admin-ui 184532 ./upload 211112 . du命令的-k参数表示用字节表示文件/文件夹的大小。这样虽然可以正常排序,但是可读性差,字节并不是人类易读的方式,还是MB,GB更好理解。进一步调查,发现sort命令居然也有-h参数,也是为了读取人类易读格式的值。/home/projects/databook# du -hd 1 . | sort -hr 207M . 181M ./upload 3.2M ./admin-ui 2.9M ./public 472K ./markdown-files 108K ./output 24K ./certs 4.0K ./download 这样就满足了我查询磁盘空间的要求。sort命令的-r参数表示从大到小排序,因为我关注的是大文件,所以想把它们排在前面。补充:-h参数是在2009年添加到GNU sort 的。
  • [技术干货] 升级openssh前安装zlib报异常configure aborting
    事情是这样的,因为系统漏洞问题,需要升级openssh,从OpenSSH_9.3p1升级到OpenSSH_9.3p2系统版本:CentOS 7升级OpenSSH_9.3p2之前需要先升级zlib从官网下载wget https://www.zlib.net/zlib-1.3.1.tar.gz解压tar -zxvf zlib-1.3.1.tar.gz cd zlib-1.3.1 ./configure --prefix=/usr/zlib执行配置的时候报错** ./configure aborting. 在其他服务器上执行的时候是没有报错的,查了一下,需要安装build-essential,但是CentOS没有build-essential,所以问题应该不在这里查看./configure.log提示libmpc.so.3不能打开find / -name libmpc.so.3没有找到这个文件 于是在之前正常配置的服务器上执行同样的命令查了一下在/usr/lib和/usr/lib64下有这两个文件,那么问题简单了,直接把这个文件从另一个服务器上考过来放到同样的地方应该就行了(因为是64位系统,所以只取lib64下的就行了)上传后重新执行./configure --prefix=/usr/zlib发现问题依然存在,继续查看日志 这次提示缺少libmpfr.so.4,同样的操作,再从别的服务器上把libmpfr.so.4平移过来,中间步骤省略了,依然是在/usr/lib64里再次执行./configure --prefix=/usr/zlib配置成功 其实写这个文章之所以把步骤写出来,就是不想让大家遇到问题只想到补充libmpc.so.3和libmpfr.so.4这两个文件,在操作的时候发现每个服务器其实缺少的文件不一定一样,所以有问题应该先分析日志,然后缺少哪个就去有文件的服务器上去找,然后平移过来就可以了转载自https://www.cnblogs.com/xiu123/p/18211147
  • Linux 防火墙只允许指定IP 端口访问
    开启和关闭防火墙命令如下:查看防火状态systemctl status firewalld2:暂时关闭防火墙systemctl stop firewalld3:永久关闭防火墙systemctl disable firewalldsystemctl stop firewalld.service4:重启防火墙systemctl enable firewalld5、查看防火墙已开通的端口:sudo firewall-cmd --list-ports6、开放指定端口:firewall-cmd --zone=public --add-port=80/tcp --permanent命令含义:–zone #作用域;–add-port=3306/tcp #添加端口,格式为:端口/通讯协议;–permanent #永久生效,没有此参数重启后失效7、从Linux防火墙中删除已开放的端口:firewall-cmd --zone=public --remove-port=6379/tcp给指定的IP开放/关闭指定的端口:添加规则// 允许ip127.0.0.1访问8888端口firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="8888" accept"//重新载入一下防火墙设置,使设置生效firewall-cmd --reload//查看已设置规则firewall-cmd --zone=public --list-rich-rules 删除规则 //限制IP为127.0.0.1的地址禁止访问8888端口即禁止访问机器firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="8888" reject" //删除已设置规则firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address=" 127.0.0.1" port protocol="tcp" port="8888" accept"转载自https://www.cnblogs.com/supyang/p/18213072
  • [常见问题汇总帖] 在虚拟机中ebpf程序跟踪socket得到的源IP地址和目的ip地址一样
    在虚拟机上进行编译和执行,得到的结果源地址IP和目的地址IP是一样的,网络用的桥接模式。在user程序中进行对百度的ping操作。而且监控网口改成了我自己的网口。但是得到的就有我虚拟机的地址,socket源和目的地址都是。这是负责储存信息的结构体,在map中作为键key。这是给结构体中源和目标地址赋值的操作函数部分。这是map,值为包的数量和大小的结构体。这是user态的输出。像是端口,协议号,包数和数据大小都能正常输出,就是这个源地址和目的地址是一样的。然后我把源和目的地址改成定值1和2.输出就是1和2,感觉这是对的(没有ping百度,是连接的vscode,走22端口)然后我又去看了这个struct __sk_buff的偏移量,确实也是不一样的,源地址n1的偏移量26,目的地址n2的偏移量30,理应得到两个不同的内容才对。这俩load_word函数得到的理应是不同的值才对。但输出的确实是同一个值。但输出就是一样的,就怀疑是struct __sk_buff结构体里面填充的源和目的地址是一样的。这个程序就是源码目录下/samples/bpf/sockex3.我不能理解为什么,也许是我没理解到程序在做什么,求救大佬指导。
  • Linux实现免密登录的配置方法【转】
    需求描述:192.168.31.10服务器的yunwei账号,想要免密登陆到192.168.31.15服务器上。直接ssh root@192.168.31.15这样登陆,不用输入密码。实现:1、在10机器上,创建运维账号。123456[root@docker01 ~]# id yunwei                检查yunwei账号是否存在id: yunwei: no such user[root@docker01 ~]# useradd yunwei           创建yunwei账号[root@docker01 ~]# su - yunwei              切换到yunwei账号[yunwei@docker01 ~]$ pwd/home/yunwei2、在yunwei账号下创建密钥123456789[yunwei@docker01 ~]$ ssh-keygen     创建密钥,一路回车Generating public/private rsa key pair.Enter file in which to save the key (/home/yunwei/.ssh/id_rsa):Created directory '/home/yunwei/.ssh'.Enter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in /home/yunwei/.ssh/id_rsa.Your public key has been saved in /home/yunwei/.ssh/id_rsa.pub.The key fingerprint is:3、复制密钥到15服务器4、验证免密登陆12[yunwei@docker01 .ssh]$ ssh root@192.168.31.15Last login: Sun Mar 26 11:21:02 2023 from 192.168.31.1补充:优化密钥创建方式,免交互创建密钥ssh-keygen -P '' -f id_rsa      免交互方式,创建密钥Generating public/private rsa key pair.Your identification has been saved in id_rsa.Your public key has been saved in id_rsa.pub.The key fingerprint is:参数说明:-t 指定要创建的密钥类型dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | RSA可能的值为“dsa”、“ecdsa”、“ecdsa-sk”、“ed25519”、“ed25519-sk”或“rsa”。当使用 RSA CA 密钥签署证书时,此标志还可用于指定所需的签名类型。可用的 RSA 签名变体是“ssh-rsa”(SHA1 签名,不推荐)、“rsa-sha2-256”和“rsa-sha2-512”(默认值)-P 密码提供(旧)密码。这里的密码,是密钥的密码,不是远程主机的密码,随便设置。但是,这就失去了免密登陆的意义。因为,设置了这个后,登陆远程主机时,就必须输入密钥密码。所以,一般这个指指定为空即可。-f 文件名指定密钥文件的文件名这里的文件名,必须指定为id_rsa,不然,把密钥推送到目标机器,依然无法实现免密登陆。总结:就三个命令123cd                          进入当前账号家目录ssh-keygen                  连续三次回车      ssh-copy-id 192.168.31.15   复制公钥到hadoop104服务器,这样,就可以免密访问hadoop104服务器这里用户账号省略,则使用当前账号进行免密登陆比如,当前账号是test1ssh-copy-id 192.168.31.15 等价与 ssh-copy-id test@192.168.31.15实现的效果是,当前服务器的test账号可以免密登陆15服务器的test账号、
  • [技术干货] Linux 服务器上配置基于SSH 密钥的身份验证及使用方法【转】
    介绍SSH(Secure Shell)是一种加密协议,用于管理和与服务器通信。在使用 Linux 服务器时,您经常会花费大量时间在通过 SSH 连接到服务器的终端会话中。虽然有几种不同的登录 SSH 服务器的方式,但在本指南中,我们将专注于设置 SSH 密钥。SSH 密钥提供了一种非常安全的登录服务器的方式。因此,这是我们建议所有用户使用的方法。SSH 密钥是如何工作的?SSH 服务器可以使用各种不同的方法对客户端进行身份验证。其中最基本的是密码身份验证,这种方法易于使用,但并不是最安全的。尽管密码以安全的方式发送到服务器,但它们通常不够复杂或长以抵御重复和持续的攻击者。现代处理能力结合自动化脚本使得破姐受密码保护的帐户成为可能。虽然还有其他方法可以增加额外的安全性(例如 fail2ban 等),但 SSH 密钥被证明是一种可靠和安全的替代方法。SSH 密钥对是两个密码安全的密钥,可用于对客户端进行 SSH 服务器身份验证。每个密钥对包括一个公钥和一个私钥。私钥由客户端保留,应绝对保密。私钥的任何泄露都将允许攻击者在不需要额外身份验证的情况下登录配置有相关公钥的服务器。作为额外的预防措施,密钥可以在磁盘上使用密码短语进行加密。相关的公钥可以自由共享,不会产生任何负面影响。公钥可用于加密只有私钥可以解密的消息。这一特性被用作使用密钥对进行身份验证的一种方式。公钥被上传到您希望能够通过 SSH 登录的远程服务器。该密钥被添加到您将要登录的用户帐户中的一个特殊文件中,称为 ~/.ssh/authorized_keys。当客户端尝试使用 SSH 密钥进行身份验证时,服务器可以测试客户端是否拥有私钥。如果客户端能够证明自己拥有私钥,将会生成一个 shell 会话或执行请求的命令。步骤 1 —— 创建 SSH 密钥配置 SSH 密钥身份验证到您的服务器的第一步是在本地计算机上生成 SSH 密钥对。为此,我们可以使用一个名为 ssh-keygen 的特殊实用程序,它包含在标准 OpenSSH 工具套件中。默认情况下,这将创建一个 3072 位的 RSA 密钥对。在本地计算机上,通过输入以下命令生成 SSH 密钥对:12[本地环境]ssh-keygen123[本地环境]生成公钥/私钥 rsa 密钥对。输入要保存密钥的文件(/home/username/.ssh/id_rsa):该实用程序将提示您选择要生成的密钥的位置。默认情况下,密钥将存储在用户主目录中的 ~/.ssh 目录中。私钥将被称为 id_rsa,相关的公钥将被称为 id_rsa.pub。通常,在这个阶段最好使用默认位置。这样做将允许您的 SSH 客户端在尝试进行身份验证时自动找到您的 SSH 密钥。如果您想选择非标准路径,请现在输入该路径,否则按 ENTER 接受默认值。如果您之前生成过 SSH 密钥对,您可能会看到类似以下的提示:123[本地环境]/home/username/.ssh/id_rsa 已经存在。覆盖(y/n)?如果选择覆盖磁盘上的密钥,您将无法再使用先前的密钥进行身份验证。在选择是时要非常小心,因为这是一个不可逆转的破坏性过程。1234[本地环境]创建目录 '/home/username/.ssh'。输入密码短语(留空表示没有密码短语):再次输入密码短语:接下来,您将被提示为密钥输入密码短语。这是一个可选的密码短语,可用于加密磁盘上的私钥文件。您可能会想知道,如果您仍然需要输入密码短语,SSH 密钥提供了哪些优势。其中一些优势包括:私有 SSH 密钥(可以受密码短语保护的部分)永远不会在网络上暴露。密码短语仅用于在本地机器上解密密钥。这意味着网络基础的破姐将无法针对密码短语进行。私钥保存在受限制的目录中。SSH 客户端将不会识别未保存在受限制目录中的私钥。密钥本身也必须具有受限制的权限(仅对所有者可用的读和写权限)。这意味着系统上的其他用户无法窥视。任何希望破解私有 SSH 密钥密码短语的攻击者必须已经访问系统。这意味着他们已经可以访问您的用户帐户或 root 帐户。如果您处于这种位置,密码短语可以防止攻击者立即登录到您的其他服务器。这将希望给您时间创建和实施新的 SSH 密钥对,并从受损的密钥中删除访问权限。由于私钥永远不会暴露在网络上,并且通过文件权限进行保护,因此该文件永远不应该对除您(和root用户)以外的任何人可访问。密码短语作为一个额外的保护层,以防这些条件被破坏。密码短语是一个可选的附加项。如果输入密码短语,您将需要在每次使用该密钥时提供它(除非您正在运行存储解密密钥的 SSH 代理软件)。我们建议使用密码短语,但如果您不想设置密码短语,可以按 ENTER 跳过此提示。1234567891011121314151617[本地环境]您的标识已保存在 /home/username/.ssh/id_rsa。您的公钥已保存在 /home/username/.ssh/id_rsa.pub。密钥指纹为:SHA256:CAjsV9M/tt5skazroTc1ZRGCBz+kGtYUIPhRvvZJYBs username@hostname密钥的随机艺术图像为:+---[RSA 3072]----+|o   ..oo.++o ..  || o o +o.o.+...   ||. . + oE.o.o  .  || . . oo.B+  .o   ||  .   .=S.+ +    ||      . o..*     ||        .+= o    ||        .=.+     ||       .oo+      |+----[SHA256]-----+现在您有了可以用于身份验证的公钥和私钥。下一步是将公钥放在您的服务器上,以便您可以使用 SSH 密钥身份验证登录。步骤 2 —— 将 SSH 公钥复制到您的服务器有多种方法可以将您的公钥上传到远程 SSH 服务器。您使用的方法在很大程度上取决于您可用的工具和当前配置的细节。以下方法都会产生相同的最终结果。最简单、最自动化的方法首先描述,其后的方法都需要额外的手动步骤。如果可以使用前面的方法,则应该遵循这些方法。使用 ssh-copy-id 复制您的公钥将公钥复制到现有服务器的最简单方法是使用一个名为 ssh-copy-id 的实用程序。由于其简单性,如果可用,建议使用此方法。ssh-copy-id 工具包含在许多发行版的 OpenSSH 软件包中,因此您的本地系统上可能已经有它。为使此方法工作,您必须当前具有基于密码的 SSH 访问权限到您的服务器。要使用此实用程序,您需要指定您想要连接到的远程主机和您具有基于密码的 SSH 访问权限的用户帐户。这是您的公共 SSH 密钥将被复制的帐户。语法是:12[本地环境]ssh-copy-id username@remote_host您可能会看到类似以下的消息:1234[本地环境]The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes这意味着您的本地计算机不认识远程主机。这将在您第一次连接到新主机时发生。输入 yes 并按 ENTER 继续。接下来,该实用程序将扫描您的本地帐户以查找我们之前创建的 id_rsa.pub 密钥。当它找到密钥时,它将提示您输入远程用户帐户的密码:1234[本地环境]/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysusername@203.0.113.1's password:输入密码(出于安全目的,您的输入不会显示)并按 ENTER。该实用程序将使用您提供的密码连接到远程主机上的帐户。然后,它将把您的 ~/.ssh/id_rsa.pub 密钥内容复制到远程帐户的主目录 ~/.ssh 中名为 authorized_keys 的文件中。您将看到以下输出:[本地环境]Number of key(s) added: 1Now try logging into the machine, with:   "ssh 'username@203.0.113.1'"and check to make sure that only the key(s) you wanted were added.此时,您的 id_rsa.pub 密钥已上传到远程帐户。您可以继续下一节。使用 SSH 复制您的公钥如果您没有 ssh-copy-id,但是您具有基于密码的 SSH 访问权限到服务器上的某个帐户,您可以使用传统的 SSH 方法上传您的密钥。我们可以通过在本地计算机上输出我们的公共 SSH 密钥的内容,并通过 SSH 连接将其传输到远程服务器。在另一端,我们可以确保我们正在使用的帐户下存在 ~/.ssh 目录,然后将我们传输的内容输出到此目录中名为 authorized_keys 的文件中。我们将使用 >> 重定向符号来追加内容而不是覆盖它。这将允许我们添加密钥而不破坏先前添加的密钥。完整命令如下:12[本地环境]cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"您可能会看到类似以下的消息:[本地环境]The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes这意味着您的本地计算机不认识远程主机。这将在您第一次连接到新主机时发生。输入 yes 并按 ENTER 继续。之后,您将被提示输入您尝试连接的帐户的密码:[本地环境]username@203.0.113.1's password:输入密码后,您的 id_rsa.pub 密钥内容将被复制到远程用户帐户的 authorized_keys 文件的末尾。如果成功,继续下一节。手动复制公钥如果您的服务器没有基于密码的 SSH 访问权限,您将不得不手动执行上述过程。您的 id_rsa.pub 文件的内容将需要以某种方式添加到远程机器上的 ~/.ssh/authorized_keys 文件中。要显示 id_rsa.pub 密钥的内容,请在本地计算机上输入以下命令:12[本地环境]cat ~/.ssh/id_rsa.pub您将看到密钥的内容,可能类似于以下内容:12[本地环境]ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== username@hostname使用您可用的任何方法访问远程主机。这可能是您的基础设施提供商提供的基于 Web 的控制台。一旦您可以访问远程服务器上的帐户,您应该确保 ~/.ssh 目录已创建。如果需要,此命令将创建该目录,如果已存在则不执行任何操作:1mkdir -p ~/.ssh现在,您可以在该目录中创建或修改 authorized_keys 文件。您可以将 id_rsa.pub 文件的内容添加到 authorized_keys 文件的末尾,如果需要的话,可以使用以下命令创建它:1echo public_key_string >> ~/.ssh/authorized_keys在上述命令中,将 public_key_string 替换为您在本地系统上执行 cat ~/.ssh/id_rsa.pub 命令的输出。它应该以 ssh-rsa AAAA... 或类似的内容开头。如果这样操作成功,您可以继续测试您的新基于密钥的 SSH 认证。步骤 3 — 使用 SSH 密钥进行身份验证如果您已成功完成上述任一过程,您应该能够 无需 使用远程帐户的密码登录到远程主机。该过程基本上是相同的:12[本地环境]ssh username@remote_host如果这是您第一次连接到此主机(如果您使用了上述最后一种方法),您可能会看到类似以下内容:1234[本地环境]The authenticity of host '203.0.113.1 (203.0.113.1)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes这意味着您的本地计算机不认识远程主机。输入 yes 然后按 ENTER 继续。如果您没有为私钥提供密码,您将立即登录。如果您在创建密钥时为私钥提供了密码,您现在需要输入它。之后,将为您在远程系统上的帐户创建一个新的 shell 会话。如果成功,继续了解如何锁定服务器。步骤 4 — 在服务器上禁用密码身份验证如果你能够使用 SSH 无需密码登录到你的账户,那么你已经成功地为你的账户配置了基于 SSH 密钥的身份验证。然而,你的基于密码的身份验证机制仍然是激活状态,这意味着你的服务器仍然容易受到破姐攻击。在完成本节中的步骤之前,请确保你的服务器上要么已经为 root 账户配置了基于 SSH 密钥的身份验证,或者更好的是,你已经为服务器上具有 sudo 权限的账户配置了基于 SSH 密钥的身份验证。这一步将禁用基于密码的登录,因此确保你仍然能够获得管理员访问权限是至关重要的。一旦上述条件为真,请使用 SSH 密钥登录到远程服务器,可以是 root 用户,也可以是具有 sudo 权限的账户。打开 SSH 守护程序的配置文件:1sudo nano /etc/ssh/sshd_config在文件中,搜索一个名为 PasswordAuthentication 的指令。这可能是被注释掉的。通过删除行首的任何 # 号来取消注释,并将值设置为 no 来启用该选项,这将禁用使用账户密码通过 SSH 登录的功能:1PasswordAuthentication no完成后保存并关闭文件。要实际实施我们刚刚做的更改,你必须重新启动服务。在大多数 Linux 发行版上,你可以使用以下命令来执行:1sudo systemctl restart ssh完成这一步后,你已成功将你的 SSH 守护程序转换为只响应 SSH 密钥。
  • [技术干货] 深入解析:在Linux系统中实现硬盘的永久性挂载
    在Linux操作系统中,磁盘管理是一项至关重要的任务,尤其是当涉及到数据存储、备份和迁移时。临时挂载硬盘虽能满足短期需求,但为了确保系统重启后硬盘依然能够自动挂载并保持数据的持久访问,我们需要了解如何进行硬盘的永久性挂载。本文将详细阐述在Linux环境中实现硬盘永久挂载的步骤、相关概念以及最佳实践。一、理解Linux磁盘挂载在Linux中,文件系统被组织成一棵目录树结构,而每个磁盘或分区必须挂载到这棵目录树中的某个节点(称为挂载点)后,才能被用户和应用程序访问。临时挂载是指通过mount命令手动将磁盘或分区挂载到指定目录,这种挂载仅在当前会话有效,一旦系统重启,挂载关系就会丢失。与此相反,永久性挂载则是指通过配置文件/etc/fstab,使磁盘在系统启动时自动挂载到指定目录。这样,无论何时重启系统,硬盘都会按照预设规则自动挂载,无需用户干预,大大提升了数据访问的便捷性和系统的稳定性。二、实现硬盘永久挂载的步骤以下是实现Linux系统中硬盘永久挂载的详细步骤:1. 准备工作识别硬盘设备:使用lsblk命令列出系统中的块设备信息,确定待挂载的硬盘设备,如/dev/sdb。如果硬盘已分区,挂载的是具体分区,如/dev/sdb1。创建挂载点:使用mkdir命令在文件系统中创建用于挂载硬盘的目录,如/mnt/data。2. 格式化硬盘(如有必要)如果硬盘尚未格式化或需要更改文件系统,使用mkfs系列命令进行格式化。例如,使用EXT4文件系统格式化/dev/sdb1:sudo mkfs.ext4 /dev/sdb13. 临时挂载测试在正式配置永久挂载前,先通过mount命令临时挂载硬盘以验证其工作正常:sudo mount /dev/sdb1 /mnt/data现在,你可以访问/mnt/data目录,查看硬盘内容。无误后,执行umount /mnt/data卸载硬盘,准备进行永久挂载配置。4. 编辑/etc/fstab打开/etc/fstab文件(建议使用nano、vim等文本编辑器),在文件末尾添加新的一行,指定硬盘设备、挂载点、文件系统类型、挂载选项、dump备份标志和fsck检查顺序:/dev/sdb1 /mnt/data ext4 defaults 0 0各字段含义如下:/dev/sdb1:待挂载的硬盘设备或分区。/mnt/data:挂载点,即硬盘将挂载到的目录。ext4:文件系统类型,根据实际情况填写,如XFS、Btrfs等。defaults:挂载选项,包括rw(读写)、auto(自动挂载)、exec(允许执行)、suid(保留SUID位)等默认设置。可根据需要添加其他选项,如noatime、nodiratime优化性能。0:dump备份工具的检查级别,0表示不进行备份。0:fsck磁盘检查顺序,根分区为1,其余按需递增,0表示不进行检查。5. 测试fstab配置保存并关闭/etc/fstab后,使用mount -a命令重新加载所有fstab条目,检查新增的挂载配置是否正确:sudo mount -a `` 若无错误提示,说明配置成功。重启系统后,硬盘将自动挂载到指定目录。 **三、最佳实践与注意事项** - **使用UUID而非设备名**:设备名(如`/dev/sda1`)可能会因系统环境变化而改变,导致fstab配置失效。使用`blkid`命令获取硬盘UUID,并在fstab中使用UUID代替设备名,可确保挂载的稳定性。 - **合理设置挂载选项**:根据硬盘用途调整挂载选项,如对日志盘设置`noatime`以减少不必要的I/O操作,对数据库数据盘设置`data=ordered`确保数据一致性等。 - **定期备份fstab**:修改`/etc/fstab`前做好备份,防止误操作导致数据无法访问。同时,定期审查fstab配置,确保其与实际硬件、存储需求相符。 - **监控挂载状态**:借助`dmesg`、`journalctl`、`systemctl status`等命令或工具监控系统启动时的挂载过程,及时发现并解决挂载问题。
  • [技术干货] Linux系统编程-(pthread)线程创建与使用
    1. 前言前面文章介绍了Linux下进程的创建、管理、使用、通信,了解了多进程并发;这篇文章介绍Linux下线程的基本使用。线程与进程的区别 (1)进程: 是操作系统调度最小单位。 Linux下可以通过ps、top等命令查看进程的详细信息。 (2)线程: 是进程调度的最小单位,每个进程都有一个主线程。在进程里主要做事情就是线程。(3)在全系统中,进程ID是唯一标识,对于进程的管理都是通过PID来实现的。每创建一个进程,内核去中就会创建一个结构体来存储该进程的全部信息,每一个存储进程信息的节点也都保存着自己的PID。需要管理该进程时就通过这个ID来实现(比如发送信号)。当子进程结束要回收时(子进程调用exit()退出或代码执行完),需要通过wait()系统调用来进行,未回收的消亡进程会成为僵尸进程,其进程实体已经不复存在,但会虚占PID资源,因此回收是有必要的。对于线程而言,若要主动终止需要调用pthread_exit() ,主线程需要调用pthread_join()来回收(前提是该线程没有设置 “分离属性”)。像线发送线程信号也是通过线程ID实现进程间的通信方式: A.共享内存 B.消息队列 C.信号量 D.有名管道 E.无名管道 F.信号 G.文件 H.socket 线程间的通信方式: A.互斥量 B.自旋锁 C.条件变量 D.读写锁 E.线程信号 F.全局变量进程间采用的通信方式要么需要切换内核上下文,要么要与外设访问(有名管道,文件)。所以速度会比较慢。而线程采用自己特有的通信方式的话,基本都在自己的进程空间内完成,不存在切换,所以通信速度会较快。也就是说,进程间与线程间分别采用的通信方式,除了种类的区别外,还有速度上的区别。说明: 当运行多线程的进程捕获到信号时,只会阻塞主线程,其他子线程不会影响会继续执行。2. 线程相关函数介绍2.1 创建线程pthread_create是Unix操作系统(Unix、Linux等)的创建线程的函数。 编译时需要指定链接库:-lpthread 函数原型#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);参数介绍第一个参数为指向线程标识符的指针。 第二个参数用来设置线程属性。默认可填NULL。 第三个参数是线程运行函数的起始地址。 最后一个参数是运行函数的参数。不需要参数可填NULL。 Linux下查看函数帮助:# man pthread_create返回值: 若线程创建成功,则返回0。若线程创建失败,则返回出错编号。 线程创建成功后, attr参数用于指定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向线程工作函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。示例:#include <stdio.h>#include <pthread.h>​//线程函数1void *pthread_func1(void *arg){ while(1) { printf("线程函数1正在运行.....\n"); sleep(2); }}​//线程函数2void *pthread_func2(void *arg){ while(1) { printf("线程函数2正在运行.....\n"); sleep(2); }}​int main(int argc,char **argv){ pthread_t thread_id1; pthread_t thread_id2; /*1. 创建线程1*/ if(pthread_create(&thread_id1,NULL,pthread_func1,NULL)) { printf("线程1创建失败!\n"); return -1; } /*2. 创建线程2*/ if(pthread_create(&thread_id2,NULL,pthread_func2,NULL)) { printf("线程2创建失败!\n"); return -1; } /*3. 等待线程结束,释放线程的资源*/ pthread_join(thread_id1,NULL); pthread_join(thread_id2,NULL); return 0;}​//gcc pthread_demo_code.c -lpthread2.2 退出线程线程通过调用pthread_exit函数终止执行,就如同进程在结束时调用exit函数一样。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针,该返回值可以通过pthread_join函数的第二个参数得到。函数原型#include <pthread.h>void pthread_exit(void *retval);参数解析 线程的需要返回的地址。 注意: 线程结束必须释放线程堆栈,就是说线程函数必须调用pthread_exit()结束,否则直到主进程函数退出才释放2.3 等待线程结束pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable(结合属性)属性。 函数原型#include <pthread.h>int pthread_join(pthread_t thread, void **retval);参数 第一个参数: 线程标识符,即线程ID,标识唯一线程。 最后一个参数: 用户定义的指针,用来存储被等待线程返回的地址。 返回值 0代表成功。 失败,返回的则是错误号。 接收线程返回值示例://退出线程pthread_exit ("线程已正常退出");//接收线程的返回值void *pth_join_ret1;pthread_join( thread1, &pth_join_ret1);2.4 线程分离属性创建一个线程默认的状态是joinable(结合属性),如果一个线程结束运行但没有调用pthread_join,则它的状态类似于进程中的Zombie Process(僵死进程),即还有一部分资源没有被回收(退出状态码),所以创建线程者应该pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源(类似于进程的wait,waitpid)。但是调用pthread_join(pthread_id)函数后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。pthread_detach函数可以将该线程的状态设置为detached(分离状态),则该线程运行结束后会自动释放所有资源。 函数原型#include <pthread.h>int pthread_detach(pthread_t thread);参数 线程标识符 返回值 0表示成功。错误返回错误码。 EINVAL线程并不是一个可接合线程。 ESRCH没有线程ID可以被发现。2.5 获取当前线程的标识符pthread_self函数功能是获得线程自身的ID。 函数原型#include <pthread.h>pthread_t pthread_self(void);返回值 当前线程的标识符。 pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则显示结果出问题。2.6 自动清理线程资源线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序。用于程序异常退出的时候做一些善后的资源清理。 在POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数用于自动释放资源。从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用 pthread_exit()和异常终止)都将执行pthread_cleanup_push()所指定的清理函数。注意:pthread_cleanup_push函数与pthread_cleanup_pop函数需要成对调用。 函数原型void pthread_cleanup_push(void (*routine)(void *),void *arg); //注册清理函数void pthread_cleanup_pop(int execute); //释放清理函数参数 void (*routine)(void *) :处理程序的函数入口。 void *arg :传递给处理函数的形参。 int execute:执行的状态值。 0表示不调用清理函数。1表示调用清理函数。导致清理函数调用的条件:调用pthread_exit()函数pthread_cleanup_pop的形参为1。 注意:return不会导致清理函数调用。2.7 自动清理线程示例代码#include <stdio.h>#include <pthread.h>#include <stdlib.h>​//线程清理函数void routine_func(void *arg){ printf("线程资源清理成功\n");} //线程工作函数void *start_routine(void *dev){ pthread_cleanup_push(routine_func,NULL);​ //终止线程 // pthread_exit(NULL); pthread_cleanup_pop(1); //1会导致清理函数被调用。0不会调用。​}​int main(int argc,char *argv[]){ pthread_t thread_id; //存放线程的标识符 /*1. 创建线程*/ if(pthread_create(&thread_id,NULL,start_routine,NULL)!=0) { printf("线程创建失败!\n"); } /*2.设置线程的分离属性*/ if(pthread_detach(thread_id)!=0) { printf("分离属性设置失败!\n"); } while(1){} return 0; }2.8 线程取消函数pthread_cancel函数为线程取消函数,用来取消同一进程中的其他线程。头文件: #include <pthread.h>函数原型:pthread_cancel(pthread_t tid);
总条数:1204 到第 页
上滑加载中