I use dpkg-query -L <package-name> to list all files belong to the specific package.
The result is a lot of files with their directory:
/.
/usr
/usr/bin
/usr/bin/tree
/usr/share
/usr/share/doc
/usr/share/doc/tree
/usr/share/doc/tree/TODO
/usr/share/doc/tree/copyright
/usr/share/doc/tree/README.gz
/usr/share/doc/tree/changelog.Debian.gz
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/tree.1.gz
Because the outpu is too many,i always use this command like this:
dpkg-query -L tree > tree.txt
My question is how to change the view of the list in tree.txt to become more human readable,let the output be sorted by their directory prefix.
The rpm -ql <package-name> comand has the same use on Centos.
If you are only interested in the folders:
dpkg -L <pkg-name> | xargs -I{} dirname {} | sort -u
A version which groups files by directory could be done using a shell function:
lspkg() {
pkg="${1}"
if [ -t 1 ] ; then
color_dir=$'\x1b\x5b34;1m'
color_link=$'\x1b\x5b36m'
color_end=$'\x1b\x5b0m'
fi
LANG=C dpkg -L "${pkg}" \
| awk -F: '{printf "%s%s\n",$NF,(NF>1?" (pkg set link)":"")}' \
| sort \
| while read -r file ; do
if [ -d "${file}" ] ; then
echo "${color_dir}${file}${color_end}"
elif /bin/grep -q 'set link)' <<< "$file" ; then
echo " - ${color_link}${file}${color_end}"
else
echo " - ${file}"
fi
done
}
Related
I have a DEB package which dynamically creates a chroot filesystem in package postinst helper script. The package works fine for x86, amd64, and arm64 on Debian Stretch/Buster/Bullseye and Ubuntu Bionic/Focal/Jammy. However, I recently tried to install it on Raspbian arm32 and it failed.
The problem is that the pathname of the nsswitch libraries is constructed differently than on the other platforms. In other words, the piece meal assembly of the library path using uname -m is not matching what's present in the file-system.
#!/bin/bash -eu
U=chroot_user
UHOME=/home/$U
ARCH=$(uname -m)
function add_executable () {
FROM="$1"; shift
TO="$(basename $FROM)"
if [ $# -ge 1 ]; then
TO=$1; shift
fi
cp "$FROM" "$UHOME/bin/$TO"
ldd "$FROM" | grep "=> /" | awk '{print $3}' | xargs -I '{}' cp '{}' $UHOME/lib/
LIBNAME="ld-linux-$(echo $ARCH | tr '_' '-').so*"
if compgen -G "/lib64/${LIBNAME}" > /dev/null; then
cp /lib64/${LIBNAME} $UHOME/lib64/
elif compgen -G "/lib/${LIBNAME}" > /dev/null; then
cp /lib/${LIBNAME} $UHOME/lib/
fi
}
if [ "$1" = "configure" ]; then
# Create a system user that has restricted bash as its login shell.
IS_USER=$(grep $U /etc/passwd || true)
if [ ! -z "$IS_USER" ]; then
killall -u $U || true
userdel -f $U > /dev/null 2>&1 || true
fi
adduser --system --home ${UHOME} --no-create-home --group --shell /bin/rbash ${U}
# Create a clean usable chroot
rm -rf $UHOME
mkdir -p $UHOME
mkdir -p $UHOME/dev/
mknod -m 666 $UHOME/dev/null c 1 3
mknod -m 666 $UHOME/dev/tty c 5 0
mknod -m 666 $UHOME/dev/zero c 1 5
mknod -m 666 $UHOME/dev/random c 1 8
mknod -m 644 $UHOME/dev/urandom c 1 9
chown root:root $UHOME
chmod 0755 $UHOME
mkdir -p $UHOME/bin
mkdir -p $UHOME/etc
mkdir -p $UHOME/lib
mkdir -p $UHOME/usr
cd $UHOME/usr
ln -s ../bin bin
cd - > /dev/null
cd $UHOME
ln -s lib lib64
cd - > /dev/null
mkdir $UHOME/lib/${ARCH}-linux-gnu
cp /lib/${ARCH}-linux-gnu/libnss* $UHOME/lib/${ARCH}-linux-gnu
cat <<EOT>$UHOME/etc/nsswitch.conf
passwd: files
group: files
EOT
chmod 0444 $UHOME/etc/nsswitch.conf
echo "127.0.0.1 localhost" > $UHOME/etc/hosts
chmod 0444 $UHOME/etc/hosts
if [ -d /etc/terminfo/ ]; then
cp -R /etc/terminfo $UHOME/etc
fi
if [ -d /lib/terminfo/ ]; then
cp -R /lib/terminfo $UHOME/lib
fi
# Add restricted bash and ssh/scp executables into the chroot. There is no
# need for any other executable.
add_executable /bin/bash rbash
add_executable /usr/bin/ssh
add_executable /usr/bin/scp
add_executable /bin/date
add_executable /bin/ls
add_executable /bin/rm
add_executable /bin/mv
add_executable /bin/cp
grep $U /etc/passwd > $UHOME/etc/passwd
grep $U /etc/group > $UHOME/etc/group
mkdir -p $UHOME/.ssh
chmod 700 $UHOME/.ssh
chown -R $U:$U $UHOME/.ssh
# When using SSH to get out of the jail onto localhost machine, we don't want
# to be constantly told about fingerprints and permanently added hosts
mkdir -p $UHOME/home/$U/.ssh
chmod 0700 $UHOME/home/$U/.ssh
chown -R $U:$U $UHOME/home/$U
fi
#DEBHELPER#
exit 0
# vim: set ts=2 sw=2 tw=0 et :
Not in the expected location ... well, more like: the architecture type in uname's output doesn't match the directory name you want to construct ...
But you could find the directory in a different way, since you're on apt based distros.
dpkg -L libnss3 | awk '/libnss3.so/{gsub(/\/libnss3.so/,"",$0);print}'
This worked for me on both Ubuntu 20.04 and Raspbian GNU/Linux 10 (buster)
Raspbian:
$ dpkg -L libnss3 | awk '/libnss3.so/{gsub(/\/libnss3.so/,"",$0);print}'
/usr/lib/arm-linux-gnueabihf
Ubuntu:
$ dpkg -L libnss3 | awk '/libnss3.so/{gsub(/\/libnss3.so/,"",$0);print}'
/usr/lib/x86_64-linux-gnu
The following commands work on my terminal but not in my shell script. I later found out that my terminal was /bin/tcsh. Can somebody tell me what changes I need to do for /bin/sh. Here are the commands I need to change:
cp source_dir/*/dir1/*.xml destination_dir/
Error in sh-> cp: cannot stat `source_dir/*/dir1/*.xml': No such file or directory
sed -i "s+${initial_name}+${final_name}+" $file_name
This one does not complain but does not work as well.
I am adding an example for testing. The code tends to rename the names of xml files and also the contents of xml files. For example-
The file name crr.ya.na.aa.xml should be changed to aa.xml
The same name inside crr.ya.na.aa.xml should also be changed from crr.ya.na.aa to aa
Here is the code:
#!/bin/sh
# Create dir structure for testing
rm -rf audience
mkdir audience
mkdir audience/dir1 audience/dir2 audience/dir3
mkdir audience/dir1/ipxact audience/dir2/ipxact audience/dir3/ipxact
touch audience/dir1/ipxact/crr.ya.na.aa.xml
echo "<spirit:name>crr.ya.na.aa</spirit:name>" > audience/dir1/ipxact/crr.ya.na.aa.xml
touch audience/dir2/ipxact/crr.ya.na.bb.xml
echo "<spirit:name>crr.ya.na.bb</spirit:name>" > audience/dir2/ipxact/crr.ya.na.bb.xml
touch audience/dir3/ipxact/crr.ya.na.cc.xml
echo "<spirit:name>crr.ya.na.cc</spirit:name>" > audience/dir3/ipxact/crr.ya.na.cc.xml
# Create a dir for ipxact_drop files if it does not exist
mkdir -p ipxact_drop
rm -rf ipxact_drop/*
cp audience/*/ipxact/*.xml ipxact_drop/
ls ipxact_drop/ > ipxact_drop_files.log
cat ipxact_drop_files.log | \
awk '{ split($0,a,"."); print a[length(a)-1] "." a[length(a)] }' ipxact_drop_files.log > file_names.log
cat ipxact_drop_files.log | \
awk '{ split($0,a,"."); print "mv ipxact_drop/" $0 " ipxact_drop/" a[length(a)-1] "." a[length(a)] }' ipxact_drop_files.log > command.log
chmod +x command.log
./command.log
while read line
do
echo ipxact_drop/$line
initial_name=`grep -m 1 crr ipxact_drop/$line | sed -e 's/<spirit:name>//' | sed -e 's/<\/spirit:name>//' `
final_name="${line%.*}"
echo $initial_name
echo $final_name
sed -i "s+${initial_name}+${final_name}+" ipxact_drop/$line
done < file_names.log
echo " ***** SCRIPT RUN FINISHED *****"
Only the sed command at the end is not working
I was reading some other posts and understood that xml files can have problems with scripts. Here is what that worked for me upto now.
To remove cp error: replace #!/bin/sh -f with #!/bin/sh
To remove sed error for the test input: replace sed -i ...... with sed -i.back ....
#!/bin/bash
for FILE in *1000000.wgt; do
BASE=${FILE%1000000.wgt}
[[ -e $BASE.trs && -e $BASE.1000000.wgt ]] && cp "$FILE" "$BASE.trs" "$BASE.wav" /some/dir
done
This script does what you need according to your commment.
eg: 'xyz_100000.prm' is to be copied with name 'xyz_full.prm' at the same location.
#!/bin/sh
IFS=$'\n'
for FILE in *1000000.prm; do
new_name=$(echo "$FILE" | sed "s/1000000.prm$/full.prm/")
cp "$FILE" "$new_name"
done
Demonstration:
➜ ls
a1000000.prm b1000000.prm copy.sh
➜ ./copy.sh
➜ ls
afull.prm bfull.prm copy.sh
I'd suggest this:
for i in *1000000.prm; do mv $i ${i%1000000.prm}full.prm; done
Read Parameter expansion section from bash man page.
#!/bin/sh
LOCAL=/var/local
TMP=/var/tmp
URL=http://um10.eset.com/eset_upd
USER=""
PASSWD=""
WGET="wget --user=$USER --password=$PASSWD -t 15 -T 15 -N -nH -nd -q"
UPDATEFILE="update.ver"
cd $LOCAL
CMD="$WGET $URL/$UPDATEFILE"
eval "$CMD" || exit 1;
if [ -n "`file $UPDATEFILE|grep -i rar`" ]; then
(
cd $TMP
rm -f $TMP/$UPDATEFILE
unrar x $LOCAL/$UPDATEFILE ./
)
UPDATEFILE=$TMP/$UPDATEFILE
URL=`echo $URL|sed -e s:/eset_upd::`
fi
TMPFILE=$TMP/nod32tmpfile
grep file=/ $UPDATEFILE|tr -d \\r > $TMPFILE
FILELIST=`cut -c 6- $TMPFILE`
rm -f $TMPFILE
echo "Downloading updates..."
for FILE in $FILELIST; do
CMD="$WGET \"$URL$FILE\""
eval "$CMD"
done
cp $UPDATEFILE $LOCAL/update.ver
perl -i -pe 's/\/download\/\S+\/(\S+\.nup)/\1/g' $LOCAL/update.ver
echo "Done."
So I have this code to download definitions for my antivirus. The only problem is that, it downloads all files everytime i run script. Is it possible to implement some sort file checking ?, let's say for example,
"if that file is present and have same filesize skip it"
Bash Linux
The -nc argument to wget will not re-fetch files that already exist. It is, however, not compatible with the -N switch. So you'll have to change your WGET line to:
WGET="wget --user=$USER --password=$PASSWD -t 15 -T 15 -nH -nd -q -nc"
I'm trying to port some jenkins bash scripts from Ubuntu to OS X. The linux (and I think it is originally GNU) chmod has a --reference option that allows copying the mode from a reference file. I am looking for the equivalent code for OS X, preferably without installing extra packages. Even better would be a cross-platform solution.
The concrete snippet:
# expand all the templates
find "$OUTPUT_PATH" -name "*.template" | while read FILE ; do
sed \
-e "s/%{NAME}/$OPTION_NAME/g" \
-e "s/%{TITLE}/$OPTION_TITLE/g" \
-e "s/%{VERSION}/$OPTION_VERSION/g" \
-e "s/%{WHEN}/$OPTION_WHEN/g" \
"$FILE" > "${FILE%.*}"
chmod --reference="$FILE" "${FILE%.*}"
rm -f "$FILE"
done
[edit] The combination of stat -r with saving the file mode is the right combination, stat -c doesn't exist on OS X
Copy the file first and only then overwrite with a shell redirection. This should preserve the original permissions.
How about using the format switch to FreeBSD stat:
stat -f "%p" ~/.bashrc
stat -f "%Sp" ~/.bashrc
stat -f "%u:%g:%p" ~/.bashrc
If your OS X has the stat command
# expand all the templates
find "$OUTPUT_PATH" -name "*.template" | while read FILE ; do
savemod=$(stat -c "%a" "$FILE")
sed \
-e "s/%{NAME}/$OPTION_NAME/g" \
-e "s/%{TITLE}/$OPTION_TITLE/g" \
-e "s/%{VERSION}/$OPTION_VERSION/g" \
-e "s/%{WHEN}/$OPTION_WHEN/g" \
"$FILE" > "${FILE%.*}"
chmod $savemod "${FILE%.*}"
rm -f "$FILE"
done
If it doesn't have -c option, check the man page of stat under formatting. you can find similar ways to get the permission/mode of the file.