Vivek Gite 发布的文章

Q:我正在电脑上使用 Debian Linux 9 “stretch”。 我想用 NetworkManager 来建网桥。但是根本就没有添加 br0的选项。我该如何在 Linux 里使用 nmcli 来为 NetworkManager 创建或者添加网桥呢?

网桥没什么特别的,只是把两个网络连在一起。它工作在数据链路层,即 OSI 模型的第二层。网桥经常用在虚拟机或别的一些软件中。为了使用网桥而关闭桌面 Linux 上的 NetworkManager 显然是不明智的。nmcli 可以创建一个永久的网桥而不需要编辑任何文件。

本文将展示如何使用 NetworkManager 的命令行工具 nmcli 来创建网桥。

如何使用 nmcli 来创建/添加网桥

使用 NetworkManager 在 Linux 上添加网桥接口的步骤如下:

  1. 打开终端
  2. 获取当前连接状态: nmcli con show
  3. 添加新的网桥: nmcli con add type bridge ifname br0
  4. 创建子网卡: nmcli con add type bridge-slave ifname eno1 master br0
  5. 打开 br0: nmcli con up br0

让我们从细节层面看看如何创建一个名为 br0 的网桥。

获取当前网络配置

你可以通过 NetworkManager 的 GUI 来了解本机的网络连接:

Getting Network Info on Linux

也可以使用如下命令行来查看:

$ nmcli con show
$ nmcli connection show --active 

View the connections with nmcli

我有一个使用网卡 eno1 的 “有线连接”。我的系统还有一个 VPN 接口。我将要创建一个名为 br0 的网桥,并连接到 eno1

如何创建一个名为 br0 的网桥

$ sudo nmcli con add ifname br0 type bridge con-name br0
$ sudo nmcli con add type bridge-slave ifname eno1 master br0
$ nmcli connection show

Create bridge interface using nmcli on Linux

你也可以禁用 STP:

$ sudo nmcli con modify br0 bridge.stp no
$ nmcli con show
$ nmcli -f bridge con show br0

最后一条命令展示了禁用 STP 后的网桥参数:

bridge.mac-address:                     --
bridge.stp:                             no
bridge.priority:                        32768
bridge.forward-delay:                   15
bridge.hello-time:                      2
bridge.max-age:                         20
bridge.ageing-time:                     300
bridge.multicast-snooping:              yes

如何打开网桥

你必须先关闭 Wired connection 1 ,然后打开 br0

$ sudo nmcli con down "Wired connection 1"
$ sudo nmcli con up br0
$ nmcli con show

使用 ip 命令 来查看 IP 信息:

$ ip a s
$ ip a s br0

Build a network bridge with nmcli on Linux

附录: 如何在 KVM 上使用 br0

现在你可以使用 KVM/VirtualBox/VMware workstation 创建的 VM(虚拟机)来直接连接网络而非通过 NAT。使用 vi 或者 cat 命令为虚拟机创建一个名为 br0.xml 的文件:

$ cat /tmp/br0.xml

添加以下代码:

<network>
  <name>br0</name>
  <forward mode="bridge"/>
  <bridge name="br0" />
</network>

如下所示运行 virsh命令:

# virsh net-define /tmp/br0.xml
# virsh net-start br0
# virsh net-autostart br0
# virsh net-list --all

输出:

 Name State Autostart Persistent
----------------------------------------------------------
 br0 active yes yes
 default inactive no yes

阅读 man 页面获取更多信息:

$ man ip
$ man nmcli

关于作者

作者是 nixCraft 的创建者、老练的系统管理员和一个 Linux/Unix shell 脚本编程培训师。他为全球客户和各种公司工作,包括 IT,教育,国防,空间研究以及非营利组织。 他的联系方式 TwitterFacebookGoogle+


via: https://www.cyberciti.biz/faq/how-to-add-network-bridge-with-nmcli-networkmanager-on-linux/

作者:Vivek Gite 译者:kennethXia 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

有些误解认为 shell 脚本仅用于 CLI 环境。实际上在 KDE 或 Gnome 桌面下,你可以有效的使用各种工具编写 GUI 或者网络(socket)脚本。shell 脚本可以使用一些 GUI 组件(菜单、警告框、进度条等),你可以控制终端输出、光标位置以及各种输出效果等等。利用下面的工具,你可以构建强壮的、可交互的、对用户友好的 UNIX/Linux bash 脚本。

制作 GUI 应用不是一项困难的任务,但需要时间和耐心。幸运的是,UNIX 和 Linux 都带有大量编写漂亮 GUI 脚本的工具。以下工具是基于 FreeBSD 和 Linux 操作系统做的测试,而且也适用于其他类 UNIX 操作系统。

1、notify-send 命令

notify-send 命令允许你借助通知守护进程发送桌面通知给用户。这种避免打扰用户的方式,对于通知桌面用户一个事件或显示一些信息是有用的。在 Debian 或 Ubuntu 上,你需要使用 apt 命令apt-get 命令 安装的包:

sudo apt-get install libnotify-bin

CentOS/RHEL 用户使用下面的 yum 命令

sudo yum install libnotify

Fedora Linux 用户使用下面的 dnf 命令:

`$ sudo dnf install libnotify`
In this example, send simple desktop notification from the command line, enter:
### 发送一些通知 ###
notify-send "rsnapshot done :)"

示例输出:

 title=

下面是另一个附加选项的代码:

...
alert=18000
live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g')
[ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i   "BSE Sensex touched 18k";  notify_counter=1; }
...

示例输出:

 title=

这里:

  • -t 5000:指定超时时间(毫秒) (5000 毫秒 = 5 秒)
  • -u low: 设置紧急等级 (如:低、普通、紧急)
  • -i gtk-dialog-info: 设置要显示的图标名称或者指定的图标(你可以设置路径为:-i /path/to/your-icon.png

关于更多使用 notify-send 功能的信息,请参考 man 手册。在命令行下输入 man notify-send 即可看见:

man notify-send

2、tput 命令

tput 命令用于设置终端特性。通过 tput 你可以设置:

  • 在屏幕上移动光标。
  • 获取终端信息。
  • 设置颜色(背景和前景)。
  • 设置加粗模式。
  • 设置反转模式等等。

下面有一段示例代码:

#!/bin/bash

# clear the screen
tput clear

# Move cursor to screen location X,Y (top left is 0,0)
tput cup 3 15

# Set a foreground colour using ANSI escape
tput setaf 3
echo "XYX Corp LTD."
tput sgr0

tput cup 5 17
# Set reverse video mode
tput rev
echo "M A I N - M E N U"
tput sgr0

tput cup 7 15
echo "1. User Management"

tput cup 8 15
echo "2. Service Management"

tput cup 9 15
echo "3. Process Management"

tput cup 10 15
echo "4. Backup"

# Set bold mode
tput bold
tput cup 12 15
read -p "Enter your choice [1-4] " choice

tput clear
tput sgr0
tput rc

示例输出:

 title=

关于 tput 命令的详细信息,参见手册:

man 5 terminfo
man tput

3、setleds 命令

setleds 命令允许你设置键盘灯。下面是打开数字键灯的示例:

setleds -D +num

关闭数字键灯,输入:

setleds -D -num
  • -caps:关闭大小写锁定灯
  • +caps:打开大小写锁定灯
  • -scroll:关闭滚动锁定灯
  • +scroll:打开滚动锁定灯

查看 setleds 手册可看见更多信息和选项 man setleds

4、zenity 命令

zenity 命令显示 GTK+ 对话框,并且返回用户输入。它允许你使用各种 Shell 脚本向用户展示或请求信息。下面是一个 whois 指定域名目录服务的 GUI 客户端示例。

#!/bin/bash
# Get domain name
_zenity="/usr/bin/zenity"
_out="/tmp/whois.output.$$"
domain=$(${_zenity} --title  "Enter domain" \
             --entry --text "Enter the domain you would like to see whois info" )

if [ $? -eq 0 ]
then
  # Display a progress dialog while searching whois database
  whois $domain  | tee >(${_zenity} --width=200 --height=100 \
                    --title="whois" --progress \
                        --pulsate --text="Searching domain info..." \
                                    --auto-kill --auto-close \
                                    --percentage=10) >${_out}

  # Display back output
  ${_zenity} --width=800 --height=600  \
         --title "Whois info for $domain" \
         --text-info --filename="${_out}"
else
  ${_zenity} --error \
         --text="No input provided"
fi

示例输出:

 title=

参见手册获取更多 zenity 信息以及其他支持 GTK+ 的组件:

zenity --help
man zenity

5、kdialog 命令

kdialog 命令与 zenity 类似,但它是为 KDE 桌面和 QT 应用设计。你可以使用 kdialog 展示对话框。下面示例将在屏幕上显示信息:

kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found."

示例输出:

 title=

参见 《KDE 对话框 Shell 脚本编程》 教程获取更多信息。

6、Dialog

Dialog 是一个使用 Shell 脚本的应用,显示用户界面组件的文本。它使用 curses 或者 ncurses 库。下面是一个示例代码:

#!/bin/bash
dialog --title "Delete file" \
--backtitle "Linux Shell Script Tutorial Example" \
--yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60

# Get exit status
# 0 means user hit [yes] button.
# 1 means user hit [no] button.
# 255 means user hit [Esc] key.
response=$?
case $response in
   0) echo "File deleted.";;
   1) echo "File not deleted.";;
   255) echo "[ESC] key pressed.";;
esac

参见 dialog 手册获取详细信息:man dialog

关于其他用户界面工具的注意事项

UNIX、Linux 提供了大量其他工具来显示和控制命令行中的应用程序,shell 脚本可以使用一些 KDE、Gnome、X 组件集:

  • gmessage - 基于 GTK xmessage 的克隆
  • xmessage - 在窗口中显示或询问消息(基于 X 的 /bin/echo)
  • whiptail - 显示来自 shell 脚本的对话框
  • python-dialog - 用于制作简单文本或控制台模式用户界面的 Python 模块

7、logger 命令

logger 命令将信息写到系统日志文件,如:/var/log/messages。它为系统日志模块 syslog 提供了一个 shell 命令行接口:

logger "MySQL database backup failed."
tail -f /var/log/messages
logger -t mysqld -p daemon.error "Database Server failed"
tail -f /var/log/syslog

示例输出:

Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal
Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed

参见 《如何写消息到 syslog 或 日志文件》 获得更多信息。此外,你也可以查看 logger 手册获取详细信息:man logger

8、setterm 命令

setterm 命令可设置不同的终端属性。下面的示例代码会强制屏幕在 15 分钟后变黑,监视器则 60 分钟后待机。

setterm -blank 15 -powersave powerdown -powerdown 60

下面的例子将 xterm 窗口中的文本以下划线展示:

setterm -underline on;
echo "Add Your Important Message Here"
setterm -underline off

另一个有用的选项是打开或关闭光标显示:

setterm -cursor off

打开光标:

setterm -cursor on

参见 setterm 命令手册获取详细信息:man setterm

9、smbclient:给 MS-Windows 工作站发送消息

smbclient 命令可以与 SMB/CIFS 服务器通讯。它可以向 MS-Windows 系统上选定或全部用户发送消息。

smbclient -M WinXPPro <<eof
Message 1
Message 2
...
..
EOF

echo "${Message}" | smbclient -M salesguy2

参见 smbclient 手册或者阅读我们之前发布的文章:《给 Windows 工作站发送消息》:man smbclient

10、Bash 套接字编程

在 bash 下,你可以打开一个套接字并通过它发送数据。你不必使用 curl 或者 lynx 命令抓取远程服务器的数据。bash 和两个特殊的设备文件可用于打开网络套接字。以下选自 bash 手册:

  1. /dev/tcp/host/port - 如果 host 是一个有效的主机名或者网络地址,而且端口是一个整数或者服务名,bash 会尝试打开一个相应的 TCP 连接套接字。
  2. /dev/udp/host/port - 如果 host 是一个有效的主机名或者网络地址,而且端口是一个整数或者服务名,bash 会尝试打开一个相应的 UDP 连接套接字。

你可以使用这项技术来确定本地或远程服务器端口是打开或者关闭状态,而无需使用 nmap 或者其它的端口扫描器。

# find out if TCP port 25 open or not
(echo >/dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close"

下面的代码片段,你可以利用 bash 循环找出已打开的端口

echo "Scanning TCP ports..."
for p in {1..1023}
do
  (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open"
done

示例输出:

Scanning TCP ports...
22 open
53 open
80 open
139 open
445 open
631 open

下面的示例中,你的 bash 脚本将像 HTTP 客户端一样工作:

#!/bin/bash
exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80

printf "GET / HTTP/1.0
" >&3
printf "Accept: text/html, text/plain
" >&3
printf "Accept-Language: en
" >&3
printf "User-Agent: nixCraft_BashScript v.%s
" "${BASH_VERSION}"   >&3
printf "
" >&3

while read LINE <&3
do
   # do something on $LINE
   # or send $LINE to grep or awk for grabbing data
   # or simply display back data with echo command
   echo $LINE
done

参见 bash 手册获取更多信息:man bash

关于 GUI 工具和 cron 任务的注意事项

如果你 使用 crontab 来启动你的脚本,你需要使用 export DISPLAY=[用户机器]:0 命令请求本地显示或输出服务。举个例子,使用 zenity 工具调用 /home/vivek/scripts/monitor.stock.sh

@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh

你有喜欢的可以增加 shell 脚本趣味的 UNIX 工具么?请在下面的评论区分享它吧。

关于作者

本文作者是 nixCraft 创始人、一个老练的系统管理员、Linux 操作系统和 UNIX shell 编程培训师。他服务来自全球的客户和不同的行业,包括 IT 、教育、防务和空间探索、还有非营利组织。你可以在 TwitterFacebookGoogle+ 上面关注他。


via: https://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html

作者:Vivek Gite 译者:pygmalion666 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你可以通过配置 sudo 命令去嘲讽输入错误密码的用户。但是现在,当用户在 shell 输错命令时,就能嘲讽他了(滥用?)。

你好 bash-insulter

来自 Github 页面:

当用户键入错误命令,随机嘲讽。它使用了一个 bash4.x. 版本的全新内置错误处理函数,叫 command_not_found_handle

安装

键入下列 git 命令克隆一个仓库:

git clone https://github.com/hkbakke/bash-insulter.git bash-insulter

示例输出:

Cloning into 'bash-insulter'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 52 (delta 12), reused 12 (delta 2), pack-reused 0
Unpacking objects: 100% (52/52), done.

用文本编辑器,比如说使用 vi,编辑你的 ~/.bashrc 或者 /etc/bash.bashrc 文件:

$ vi ~/.bashrc

在其后追加这一行(具体了解请查看 if..else..fi 声明source 命令):

if [ -f $HOME/bash-insulter/src/bash.command-not-found ]; then
    source $HOME/bash-insulter/src/bash.command-not-found
fi

保存并关闭文件。重新登录,如果不想退出账号也可以手动运行它:

$ . $HOME/bash-insulter/src/bash.command-not-found

如何使用它?

尝试键入一些无效命令:

$ ifconfigs
$ dates

示例输出:

一个有趣的 bash 钩子功能,嘲讽输入了错误命令的你。

自定义

你需要编辑 $HOME/bash-insulter/src/bash.command-not-found

$ vi $HOME/bash-insulter/src/bash.command-not-found

示例代码:

command_not_found_handle () {
    local INSULTS=(
        "Boooo!"
        "Don't you know anything?"
        "RTFM!"
        "Hahaha, n00b!"
        "Wow! That was impressively wrong!"
        "What are you doing??"
        "Pathetic"
        "...and this is the best you can do??"
        "The worst one today!"
        "n00b alert!"
        "Your application for reduced salary has been sent!"
        "lol"
        "u suk"
        "lol... plz"
        "plz uninstall"
        "And the Darwin Award goes to.... ${USER}!"
        "ERROR_INCOMPETENT_USER"
        "Incompetence is also competence"
        "Bad."
        "Fake it till you make it!"
        "What is this...? Amateur hour!?"
        "Come on! You can do it!"
        "Nice try."
        "What if... you type an actual command the next time!"
        "What if I told you... it is possible to type valid commands."
        "Y u no speak computer???"
        "This is not Windows"
        "Perhaps you should leave the command line alone..."
        "Please step away from the keyboard!"
        "error code: 1D10T"
        "ACHTUNG! ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS! DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN. IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS. ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN."
        "Pro tip: type a valid command!"
    )

    # 设置“随机”种子发生器 
    RANDOM=$(date +%s%N)
    VALUE=$((${RANDOM}%2))

    if [[ ${VALUE} -lt 1 ]]; then
        printf "\n  $(tput bold)$(tput setaf 1)$(shuf -n 1 -e "${INSULTS[@]}")$(tput sgr0)\n\n"
    fi

    echo "-bash: $1: command not found"

    # 无效命令,常规返回已存在的代码
    return 127
}

赠品:sudo 嘲讽

编辑 sudoers 文件:

$ sudo visudo

追加下面这一行:

Defaults insults

或者像下面尾行增加一句嘲讽语:

Defaults !lecture,tty_tickets,!fqdn,insults

这是我的文件:

Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
## If set, sudo will insult users when they enter an incorrect password. ##
Defaults    insults

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root ALL = (ALL:ALL) ALL

# Members of the admin group may gain root privileges
% admin ALL = (ALL) ALL   

# Allow members of group sudo to execute any command
% sudo ALL = (ALL:ALL) ALL   

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

试一试:

$ sudo -k # 清除缓存,从头开始
$ sudo ls /root/
$ sudo -i

样例对话:

当输入错误密码时,你会被一个有趣的的 sudo 嘲讽语戏弄。

赠品:你好 sl

sl 或是 UNIX 经典捣蛋软件 游戏。当你错误的把 ls 输入成 sl,将会有一辆蒸汽机车穿过你的屏幕。

$ sl

Linux / UNIX 桌面乐趣: 蒸汽机车


via: https://www.cyberciti.biz/howto/insult-linux-unix-bash-user-when-typing-wrong-command/

作者:Vivek Gite 译者:CYLeft 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Q:我是一个新 Debian Linux 用户,我想为 Debian Linux 上运行的虚拟化环境(KVM)设置网桥。那么我该如何在 Debian Linux 9.x 服务器上的 /etc/network/interfaces 中设置桥接网络呢?

如何你想为你的虚拟机分配 IP 地址并使其可从你的局域网访问,则需要设置网络桥接器。默认情况下,虚拟机使用 KVM 创建的专用网桥。但你需要手动设置接口,避免与网络管理员发生冲突。

怎样安装 brctl

输入以下 apt-get 命令

$ sudo apt install bridge-utils

怎样在 Debian Linux 上设置网桥

你需要编辑 /etc/network/interface 文件。不过,我建议在 /etc/network/interface.d/ 目录下放置一个全新的配置。在 Debian Linux 配置网桥的过程如下:

步骤 1 - 找出你的物理接口

使用 ip 命令

$ ip -f inet a s

示例输出如下:

2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
 inet 192.168.2.23/24 brd 192.168.2.255 scope global eno1
 valid_lft forever preferred_lft forever

eno1 是我的物理网卡。

步骤 2 - 更新 /etc/network/interface 文件

确保只有 lo(loopback 在 /etc/network/interface 中处于活动状态)。(LCTT 译注:loopback 指本地环回接口,也称为回送地址)删除与 eno1 相关的任何配置。这是我使用 cat 命令 打印的配置文件:

$ cat /etc/network/interface
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
 
source /etc/network/interfaces.d/*
 
# The loopback network interface
auto lo
iface lo inet loopback

步骤 3 - 在 /etc/network/interfaces.d/br0 中配置网桥(br0)

使用文本编辑器创建一个文本文件,比如 vi 命令:

$ sudo vi /etc/network/interfaces.d/br0

在其中添加配置:

## static ip config file for br0 ##
auto br0
iface br0 inet static
    address 192.168.2.23
    broadcast 192.168.2.255
    netmask 255.255.255.0
    gateway 192.168.2.254
    # If the resolvconf package is installed, you should not edit
    # the resolv.conf configuration file manually. Set name server here
    #dns-nameservers 192.168.2.254
    # If you have muliple interfaces such as eth0 and eth1
    # bridge_ports eth0 eth1
    bridge_ports eno1
    bridge_stp off # disable Spanning Tree Protocol
    bridge_waitport 0 # no delay before a port becomes available
    bridge_fd 0 # no forwarding delay

如果你想使用 DHCP 来获得 IP 地址:

## DHCP ip config file for br0 ##
auto br0
 
# Bridge setup
 iface br0 inet dhcp
  bridge_ports eno1

在 vi/vim 中保存并关闭文件

步骤 4 - 重新启动网络服务

在重新启动网络服务之前,请确保防火墙已关闭。防火墙可能会引用较老的接口,例如 eno1。一旦服务重新启动,你必须更新 br0 接口的防火墙规则。键入以下命令重新启动防火墙:

$ sudo systemctl restart network-manager

确认服务已经重新启动:

$ systemctl status network-manager

借助 ip 命令寻找新的 br0 接口和路由表:

$ ip a s $ ip r $ ping -c 2 cyberciti.biz

示例输出:

你可以使用 brctl 命令查看网桥有关信息:

$ brctl show

显示当前网桥:

$ bridge link

关于作者

作者是 nixCraft 的创建者,也是经验丰富的系统管理员,DevOps 工程师以及 Linux 操作系统/ Unix shell 脚本的培训师。通过订阅 RSS/XML 流 或者 每周邮件推送获得关于 SysAdmin, Linux/Unix 和开源主题的最新教程。


via: https://www.cyberciti.biz/faq/how-to-configuring-bridging-in-debian-linux/

作者:Vivek GIte 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Q:我想在 Linux / 类Unix 系统上使用 awk 打印文件名。 如何使用 awk 的 BEGIN 特殊模式打印文件名? 我可以使用 gawk/awk 打印当前输入文件的名称吗?(LCTT 译注:读者最好能有一些 awk 的背景知识,否则阅读本文的时候会有一些困惑)

FILENAME 变量中存放着当前输入文件的名称。 您可以使用 FILENAME 显示或打印当前输入文件名,如果在命令行中未指定文件,则 FILENAME 的值为 - (标准输入)(LCTT 译注:多次按下回车键即可看到效果)。 但是,除非由 getline 设置,否则 FILENAMEBEGIN 特殊模式中未定义。

使用 awk 打印文件名

使用语法如下:

awk '{ print FILENAME }' fileNameHere 
awk '{ print FILENAME }' /etc/hosts

因 awk 逐行读取文件,因此,你可能看到多个文件名,为了避免这个情况,你可以使用如下的命令:(LCTT 译注:FNR 表示当前记录数,只在文件中有效)

awk 'FNR == 1{ print FILENAME } ' /etc/passwd 
awk 'FNR == 1{ print FILENAME } ' /etc/hosts

使用 awk 的 BEGIN 特殊规则打印文件名

使用下面的语法:(LCTT 译注:ARGV[I] 表示输入的第 i 个参数)

awk 'BEGIN{print ARGV[1]}' fileNameHere 
awk 'BEGIN{print ARGV[1]}{ print "someting or do something on data" }END{}' fileNameHere 
awk 'BEGIN{print ARGV[1]}' /etc/hosts

示例输出:

/etc/hosts

然而,ARGV[1] 并不是每一次都能奏效,例如:

ls -l /etc/hosts | awk 'BEGIN{print ARGV[1]} { print }'

你需要将它修改如下(假设 ls -l 只产生一行输出):

ls -l /etc/hosts | awk '{ print "File: " $9 ", Owner:" $3 ", Group: " $4 }'

示例输出:

File: /etc/hosts, Owner:root, Group: root

处理由通配符指定的多个文件名

使用如下的示例语法:

awk '{ print FILENAME; nextfile } ' *.c 
awk 'BEGIN{ print "Starting..."} { print FILENAME; nextfile }END{ print "....DONE"} ' *.conf

示例输出:

Starting...
blkid.conf
cryptconfig.conf
dhclient6.conf
dhclient.conf
dracut.conf
gai.conf
gnome_defaults.conf
host.conf
idmapd.conf
idnalias.conf
idn.conf
insserv.conf
iscsid.conf
krb5.conf
ld.so.conf
logrotate.conf
mke2fs.conf
mtools.conf
netscsid.conf
nfsmount.conf
nscd.conf
nsswitch.conf
openct.conf
opensc.conf
request-key.conf
resolv.conf
rsyncd.conf
sensors3.conf
slp.conf
smartd.conf
sysctl.conf
vconsole.conf
warnquota.conf
wodim.conf
xattr.conf
xinetd.conf
yp.conf
....DONE

nextfile 告诉 awk 停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 更多信息,请参见 awk/gawk 命令手册页:

man awk 
man gawk

关于作者

作者是 nixCraft 的创立者,也是经验丰富的系统管理员和 Linux/Unix shell 脚本的培训师。 他曾与全球各行各业的客户合作,涉及 IT,教育,国防和空间研究以及非营利部门等多个行业。 您可以在 TwitterFacebookGoogle+上关注他。 可以通过订阅我的 RSS 来获取更多的关于系统管理,Linux/Unix ,和开源主题的相关资料。


via: https://www.cyberciti.biz/faq/how-to-print-filename-with-awk-on-linux-unix/

作者:Vivek Gite 译者:amwps290 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Q:如何对我存放在 /var/www/html/ 目录中的所有文件设置只读权限?

你可以使用 chmod 命令对 Linux/Unix/macOS/OS X/*BSD 操作系统上的所有文件来设置只读权限。这篇文章介绍如何在 Linux/Unix 的 web 服务器(如 Nginx、 Lighttpd、 Apache 等)上来设置只读文件权限。

如何设置文件为只读模式

语法为:

### 仅针对文件 ###
chmod 0444 /var/www/html/*
chmod 0444 /var/www/html/*.php

如何设置目录为只读模式

语法为:

### 仅针对目录 ###
chmod 0444 /var/www/html/
chmod 0444 /path/to/your/dir/
# ***************************************************************************
# 假如 web 服务器的用户/用户组是 www-data,文件拥有者是 ftp-data 用户/用户组
# ***************************************************************************
# 设置目录所有文件为只读
chmod -R 0444 /var/www/html/
# 设置文件/目录拥有者为 ftp-data
chown -R ftp-data:ftp-data /var/www/html/
# 所有目录和子目录的权限为 0445 (这样 web 服务器的用户或用户组就可以读取我们的文件)
find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 "{}"

找到所有 /var/www/html 下的所有文件(包括子目录),键入:

### 仅对文件有效 ###
find /var/www/html -type f -iname "*" -print0 | xargs -I {} -0 chmod 0444 {}

然而,你需要在 /var/www/html 目录及其子目录上设置只读和执行权限,如此才能让 web 服务器能够访问根目录,键入:

### 仅对目录有效 ###
find /var/www/html -type d -iname "*" -print0 | xargs -I {} -0 chmod 0544 {}

警惕写权限

请注意在 /var/www/html/ 目录上的写权限会允许任何人删除文件或添加新文件。也就是说,你可能需要设置一个只读权限给 /var/www/html/ 目录本身。

### web根目录只读 ###
chmod 0555 /var/www/html

在某些情况下,根据你的设置要求,你可以改变文件的属主和属组来设置严格的权限。

### 如果 /var/www/html 目录的拥有人是普通用户,你可以设置拥有人为:root:root 或 httpd:httpd (推荐) ###
chown -R root:root /var/www/html/

### 确保 apache 拥有 /var/www/html/ ###
chown -R apache:apache /var/www/html/

关于 NFS 导出目录

你可以在 /etc/exports 文件中指定哪个目录应该拥有只读或者读写权限 。这个文件定义各种各样的共享在 NFS 服务器和他们的权限。如:

# 对任何人只读权限
/var/www/html *(ro,sync) 

# 对192.168.1.10(upload.example.com)客户端读写权限访问
/var/www/html 192.168.1.10(rw,sync)

关于用于 MS-Windows客户端的 Samba(CIFS)只读共享

要以只读共享 sales,更新 smb.conf,如下:

[sales]
comment = Sales Data
path = /export/cifs/sales
read only = Yes
guest ok = Yes

关于文件系统表(fstab)

你可以在 Unix/Linux 上的 /etc/fstab 文件中配置挂载某些文件为只读模式。

你需要有专用分区,不要设置其他系统分区为只读模式。

如下在 /etc/fstab 文件中设置 /srv/html 为只读模式。

/dev/sda6 /srv/html ext4 ro 1 1

你可以使用 mount 命令重新挂载分区为只读模式(使用 root 用户)

# mount -o remount,ro /dev/sda6 /srv/html

或者

# mount -o remount,ro /srv/html

上面的命令会尝试重新挂载已挂载的文件系统到 /srv/html上。这是改变文件系统挂载标志的常用方法,特别是让只读文件改为可写的。这种方式不会改变设备或者挂载点。让文件变得再次可写,键入:

# mount -o remount,rw /dev/sda6 /srv/html

# mount -o remount,rw /srv/html

Linux:chattr 命令

你可以在 Linux 文件系统上使用 chattr 命令改变文件属性为只读,如:

chattr +i /path/to/file.php
chattr +i /var/www/html/

# 查找任何在/var/www/html下的文件并设置为只读#
find /var/www/html -iname "*" -print0 | xargs -I {} -0 chattr +i {}

通过提供 -i 选项可删除只读属性:

chattr -i /path/to/file.php

FreeBSD、Mac OS X 和其他 BSD Unix 用户可使用chflags命令

### 设置只读 ##
chflags schg /path/to/file.php

### 删除只读 ##
chflags noschg /path/to/file.php

via: https://www.cyberciti.biz/faq/howto-set-readonly-file-permission-in-linux-unix/

作者:Vivek Gite 译者:yizhuoyan 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出