chattr.test 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/bin/bash
  2. [ -f testing.sh ] && . testing.sh
  3. #testing "name" "command" "result" "infile" "stdin"
  4. if [ "$(id -u)" -ne 0 ]; then
  5. echo "$SHOWSKIP: chattr (not root)"
  6. return 2>/dev/null
  7. exit
  8. fi
  9. function clean()
  10. {
  11. # We don't know whether the fs will have extents (e, typically true on the
  12. # desktop) or be encrypted (E, typically true on Android), or have data
  13. # inlined in the inode (N), or use indexed directories, so strip those out.
  14. # We also don't want to rely on chattr(1) to set a known version number or
  15. # project number, so blank out any numbers.
  16. sed -E -e 's/, (Encrypted|Extents|Indexed_directory|Inline_Data)//g;' \
  17. -e 's/[EeIN]-/--/g; s/[0-9]+/_/g'
  18. }
  19. mkdir testattr
  20. IN="cd testattr"
  21. OUT="cd .."
  22. _t="abcdefghijklmnopqrstuvwxyz"
  23. _empty="--------------------"
  24. # Check +i (immutable) works by trying to write to and remove the file.
  25. _i="----i---------------"
  26. testing "immutable" "$IN && echo "$_t" > testFile &&
  27. chattr +i testFile && lsattr testFile | clean &&
  28. date > testFile 2>/dev/null; rm testFile; chattr -i testFile;
  29. cat testFile; rm -rf testFile; $OUT " "$_i testFile\n$_t\n" "" ""
  30. # Check +a (append-only) works by failing to write and succeeding in appending.
  31. _a="-----a--------------"
  32. testing "append-only" "$IN && echo "$_t" > testFile &&
  33. chattr +a testFile &&
  34. echo $_t >> testFile &&
  35. date > testFile || lsattr testFile | clean &&
  36. chattr -a testFile; cat testFile; rm -rf testFile; $OUT" \
  37. "$_a testFile\n$_t\n$_t\n" "" ""
  38. # For the rest, just toggle the bits back and forth (where supported).
  39. # Note that some file system/kernel combinations do return success but
  40. # silently ignore your request: +T on 4.19 f2fs, or +F on 5.2 ext4,
  41. # for example, so we're deliberately a bit selective here.
  42. # f2fs in 5.6+ kernels supports compression, but you can only enable
  43. # compression on a file while it's still empty, so we skip +c too.
  44. for attr in "A" "d" "e" "j" "P" "S" "s" "t" "u"; do
  45. echo "$_t" > testFile && chattr +$attr testFile 2>/dev/null || ((++SKIP))
  46. # Check that $attr is in the lsattr output, then that - turns it back off.
  47. testing "toggle $attr" "lsattr testFile | awk '{print \$1}' > attrs;
  48. grep -q $attr attrs || cat attrs; cat testFile && chattr -$attr testFile &&
  49. lsattr testFile | clean; rm -rf testFile" "$_t\n$_empty testFile\n" "" ""
  50. done
  51. _aA="-----a-A------------"
  52. testing "multiple bits" "$IN && touch testFile &&
  53. chattr +Aa testFile && lsattr testFile | clean &&
  54. chattr -Aa testFile && lsattr testFile | clean;
  55. rm -rf testFile; $OUT" "$_aA testFile\n$_empty testFile\n" "" ""
  56. testing "multiple files" "$IN && touch fileA && touch fileB &&
  57. chattr +Aa fileA fileB && lsattr fileA fileB | clean &&
  58. chattr -Aa fileA fileB && lsattr fileA fileB | clean;
  59. rm -rf testFile*; $OUT" \
  60. "$_aA fileA\n$_aA fileB\n$_empty fileA\n$_empty fileB\n" "" ""
  61. touch testFile && chattr -v 1234 testFile 2>/dev/null || ((++SKIP))
  62. testing "-v version" "lsattr -v testFile | awk '{print \$1}' &&
  63. chattr -v 4567 testFile && lsattr -v testFile | awk '{print \$1}';
  64. rm -rf testFile" "1234\n4567\n" "" ""
  65. mkdir -p a/b/c && touch a/b/c/fA a/b/c/fB
  66. testing "-R" "chattr -R +a a && lsattr a/b/c/fA a/b/c/fB | clean &&
  67. chattr -R -a a && rm -rf a" \
  68. "$_a a/b/c/fA\n$_a a/b/c/fB\n" "" ""
  69. rm -rf a
  70. # Clean up
  71. rm -rf testattr