Проблемы с проверкой через grep

Я недостаточно -разбираюсь в cgroups, чтобы дать однозначный ответ, (и уж точно у меня нет опыта работы с cgroups начиная с 2013 года! )но на ванильной Ubuntu 16.04 cgroups v1, похоже, работают вместе:

Я разработал небольшой тест, который заставляет разветвляться от имени другого пользователя с использованием дочернего элемента sudo /bin/bash, выделенного с помощью&-флаг -H— дополнительная паранойя, чтобы заставить sudoвыполняться в домашней среде root.

cat <(whoami) /proc/self/cgroup >me.cgroup && \
sudo -H /bin/bash -c 'cat <(whoami) /proc/self/cgroup >you.cgroup' & \
sleep 2 && diff me.cgroup you.cgroup

Это дает:

1c1
< admlocal
---
> root

Для справки, это структура монтирования cgroup в моей системе:

$ mount | grep group
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
$
0
10.06.2021, 17:26
4 ответа

Если вам не нужны допустимые префиксы в переменной, вы можете использовать любое из следующих решений.

В зависимости от того, например,. feature/foo/barдолжен быть действительным или нет, вы должны удалить только последний /*или все.

Вам может понадобиться отдельный тест, чтобы проверить, содержит ли вообще branch/.

Примерcheck.sh:

#!/bin/sh

# foo/bar --> ^foo$
# foo --> ^foo$
# foo/bar/baz --> ^foo$
pattern='^'"${branch%%/*}"'$'

# search for pattern in input, suppress output
grep "$pattern" >/dev/null <<EOF
feature
test
release
EOF

echo $?

тестирование

$ branch=featur/fix./check.sh
0
$ branch=foo/fix./check.sh
1
$ branch=xfeature/fix./check.sh
1
$ branch=featurex/fix./check.sh
1

Редактировать:

Как упоминалось в комментарии Stéphane Chazelas ', приведенное выше решение может привести к неожиданным совпадениям, если предоставленное имя ветки содержит какие-либо метасимволы регулярного выражения -, например. для branch='.*'.

В зависимости от того, какие именно значения нужно проверить, этого можно избежать, заключив строки в символы-разделители, например. /.

#...
pattern="/${branch%%/*}/"
#...
fgrep "$pattern" >/dev/null <<EOF
/feature/
/test/
/release/
EOF
#...

Примерcheck2.sh:

#!/bin/sh

# removes longest match /*
# foo/bar/baz --> foo
case "${branch%%/*}" in
feature|test|release)
    echo valid 1
    ;;
*)
    echo invalid 1
    ;;
esac

# removes shortedt match /*
# foo/bar/baz --> foo/bar
case "${branch%/*}" in
feature|test|release)
    echo valid 2
    ;;
*)
    echo invalid 2
    ;;
esac

тестирование

$ branch=feature/fix./check2.sh
valid 1
valid 2
$ branch=feature/fix/bla./check2.sh
valid 1
invalid 2
$ branch=xfeature/fix./check2.sh
invalid 1
invalid 2
$ branch=featurex/fix./check2.sh
invalid 1
invalid 2
1
28.07.2021, 11:25

Если $listподразумевается как скалярная переменная, содержащая список слов, разделенных пробелом -, и вы хотите проверить, что $branchявляется одним из тех слов, за которыми следует /, за которым следует один или несколько ASCII-альнумов, в POSIX shвы могли бы сделать:

validate() (export LC_ALL=C
  list=$1 branch=$2
  case $branch in
    (*' '*) return 1;;
  esac
  case ${branch##*/} in
    ("" | *[![:alnum:]]*) return 1;;
  esac
  case " $list " in
    (*" ${branch%/*} "*) return 0;;
    (*) return 1;;
  esac
)

А потом:

if validate "$list" "$branch"; then
  echo OK
else
  echo KO
fi

Для сопоставления регулярных выражений произвольных строк (, а не строк ), POSIXly основными параметрами являются exprи его оператор :, хотя он использует базовые регулярные выражения и имеет несколько проблем с дизайном и awkи его ~оператор (, который использует расширенные регулярные выражения ).

Здесь,вы могли бы сделать (, предполагая, что ни одно из слов в $listне является оператором регулярного выражения):

validate() {
  LC_ALL=C awk -- '
    BEGIN {
      regexp = ARGV[1]
      branch = ARGV[2]
      gsub(" ", "|", regexp)
      regexp = "^("regexp")/[a-zA-Z0-9]+$"
      exit !(branch ~ regexp)
    }' "$@"
}

(здесь используется [a-zA-Z0-9]вместо [[:alnum:]], поскольку вы все еще сталкиваетесь с awkреализациями, которые не поддерживают классы символов POSIX ).

Несколько вещей, о которых следует помнить:

  • grepработает на основе строки -, поэтому вы не можете использовать ее для проверки произвольных строк, если вы не убедились, что эти строки не содержат символы новой строки.
  • В оболочках POSIX расширения параметров должны быть заключены в кавычки, иначе они подлежат разделению+подстановке (нетecho $list)
  • echoнельзя использовать для вывода произвольных данных, используйте printfвместо (, поэтому echo $listдолжно бытьprintf '%s\n' "$list").
  • Диапазоны, подобные 0-9A-Za-z, можно использовать только в локали C. В локали C [0-9A-Za-z]совпадает с [[:alnum:]].
1
28.07.2021, 11:25

Вот моя оценка из @Bodo однострочной версии:

echo $list | tr ' ' '\n' | grep '^'"${branch%%/*}"'$'; if [[ $? -eq 0 ]]; then echo  "VALID NAME"; else echo "NOPE"; exit 1; fi;
0
28.07.2021, 11:25

Когда вы сделаете это,

list="feature test release"
branch=feature/fix
echo $list| grep -e "$branch/[a-zA-Z0-9]"

(и предполагая немодифицированный $IFS, поскольку вы забыли процитировать $list), вы фактически пишете это:

echo feature test release | grep -e 'feature/fix/[a-zA-Z0-9]'

и это ищет шаблонfeature/fix/X(для любого буквенно-цифрового символа какX)в строке feature test release. Это не сработает.

Вы можете изменить формат списка на регулярное выражение и сравнить свой тег с этим

listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/"    # ^(feature|test|release)/
printf '%s\n' "$branch" | grep -E "$listRE"; echo "$?"
0
28.07.2021, 11:25

Теги

Похожие вопросы