Giải mã 100% code của các công cụ viết bằng Bash shell
Chúng tôi sẽ chỉ ra ý định, ý đồ của người viết code, mục đích của từng dòng code là gì, để làm gì trong mỗi bài học lập trình bash shell thực chiến.
Lập trình Bash shell can thiệp vào Linux kernel image
extract-vmlinux
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
# ----------------------------------------------------------------------
# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
#
# Inspired from extract-ikconfig
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
#
# (c) 2011 Corentin Chary <corentin.chary@gmail.com>
#
# ----------------------------------------------------------------------
check_vmlinux()
{
# Use readelf to check if it's a valid ELF
# TODO: find a better to way to check that it's really vmlinux
# and not just an elf
readelf -h $1 > /dev/null 2>&1 || return 1
cat $1
exit 0
}
try_decompress()
{
# The obscure use of the "tr" filter is to work around older versions of
# "grep" that report the byte offset of the line instead of the pattern.
# Try to find the header ($1) and decompress from here
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
do
pos=${pos%%:*}
tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
check_vmlinux $tmp
done
}
# Check invocation:
me=${0##*/}
img=$1
if [ $# -ne 1 -o ! -s "$img" ]
then
echo "Usage: $me <kernel-image>" >&2
exit 2
fi
# Prepare temp files:
tmp=$(mktemp /tmp/vmlinux-XXX)
trap "rm -f $tmp" 0
# That didn't work, so retry after decompression.
try_decompress '\037\213\010' xy gunzip
try_decompress '\3757zXZ\000' abcde unxz
try_decompress 'BZh' xy bunzip2
try_decompress '\135\0\0\0' xxx unlzma
try_decompress '\211\114\132' xy 'lzop -d'
try_decompress '\002!L\030' xxx 'lz4 -d'
try_decompress '(\265/\375' xxx unzstd
# Finally check for uncompressed images or objects:
check_vmlinux $img
# Bail out:
echo "$me: Cannot find vmlinux." >&2
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/extract-vmlinux
extract-ikconfig
#!/bin/sh
# ----------------------------------------------------------------------
# extract-ikconfig - Extract the .config file from a kernel image
#
# This will only work when the kernel was compiled with CONFIG_IKCONFIG.
#
# The obscure use of the "tr" filter is to work around older versions of
# "grep" that report the byte offset of the line instead of the pattern.
#
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
# Licensed under the terms of the GNU General Public License.
# ----------------------------------------------------------------------
cf1='IKCFG_ST\037\213\010'
cf2='0123456789'
dump_config()
{
if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
then
pos=${pos%%:*}
tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
if [ $? != 1 ]
then # exit status must be 0 or 2 (trailing garbage warning)
cat $tmp1
exit 0
fi
fi
}
try_decompress()
{
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
do
pos=${pos%%:*}
tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null
dump_config $tmp2
done
}
# Check invocation:
me=${0##*/}
img=$1
if [ $# -ne 1 -o ! -s "$img" ]
then
echo "Usage: $me <kernel-image>" >&2
exit 2
fi
# Prepare temp files:
tmp1=/tmp/ikconfig$$.1
tmp2=/tmp/ikconfig$$.2
trap "rm -f $tmp1 $tmp2" 0
# Initial attempt for uncompressed images or objects:
dump_config "$img"
# That didn't work, so retry after decompression.
try_decompress '\037\213\010' xy gunzip
try_decompress '\3757zXZ\000' abcde unxz
try_decompress 'BZh' xy bunzip2
try_decompress '\135\0\0\0' xxx unlzma
try_decompress '\211\114\132' xy 'lzop -d'
try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
try_decompress '\050\265\057\375' xxx unzstd
# Bail out:
echo "$me: Cannot find kernel config." >&2
exit 1
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/extract-ikconfig
Bài tập lớn
Đọc hiểu các shell script khác của Linux kernel
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/