Как передать строку, содержащую косую черту, в sed, не рассматривая ее как файл? (Нет такого каталога или файла)

Как вам уже говорили (см. Почему не работает swappiness? ), изменение swappinessвлияет только на будущие решения, принимаемые ядром, когда ему нужно освободить память. Его уменьшение не приведет к тому, что ядро ​​перезагрузит все, что было выгружено.

Ваш вывод vmstatпоказывает, что подкачка активно не используется, т. е. ваши текущие рабочие нагрузки действительно не нуждаются в выгруженных страницах.

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

Если вы действительно хотите очистить подкачку, отключите ее и -снова включите:

swapoff -a && swapon -a

0
12.05.2020, 01:48
3 ответа

Если вы хотите, чтобы вывод echo $operandбыл my, тогда ваш синтаксис в порядке, за исключением одной вещи, которой не хватает:

operand="$(echo $my_value | sed -n -e 's/^\(.*\)\/.*/\1/p')"

Вам нужно использовать echoдля переменной my_value, чтобы ее значение было отправлено на стандартный вывод, чтобы sedработал с ним. Вы получаете сообщение об ошибке, потому что на самом деле нет файла или каталога с именем my/value, который является значением вашей переменной.

Вышеупомянутая замена команды для переменной operand, включая echo, будет выводить myпри использовании echo $operand.

Другой способ сделать это с помощью:

operand="$(printf '%s\n' "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"

Это один из случаев, когда printfлучше, так как эхо не работает с другими включенными строками. Это не происходит в этом случае, но это может быть в других.

2
28.04.2021, 23:14

Конвейер в том виде, в котором вы его построили, полагается на то, что выходные данные одной команды вводятся для другой. Вы пытаетесь запустить файл с именем my/valueи, по-видимому, получаете сообщение, что такого файла нет.

Есть несколько способов сделать то, что вы хотите.

Этот метод, по-прежнему использующий конвейер, вероятно, является наиболее переносимым.

operand="$(echo "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"

Если ваша оболочка поддерживает это, это альтернатива (должна работать как минимум в bash):

operand="$(sed -n -e 's/^\(.*\)\/.*/\1/p' <<< "$my_value")"

Последний метод несколько предпочтительнее, поскольку он не вызывает дополнительный процесс для отображения значения переменной.

В любом случае рекомендуется защищать содержимое переменных двойными кавычками.

1
28.04.2021, 23:14

Как указывали другие, вы пытаетесь выполнить значение $my_valueкак команду в своей подстановке команд.

Если вы хотите удалить все после первого /в строке, используйте вместо этого подстановку команд:

my_value="this/is/my/value"
operand=${my_value%%/*}

printf '%s\n' "$operand"    # will output the string "this"

Расширение параметра ${my_value%%/*}приведет к удалению из значения $my_valueсамой длинной суффиксной строки, соответствующей /*. Это расширение стандартного параметра , которое будет выполняться оболочкой намного быстрее, чем вызов sed.

Кроме того, если значение в $my_valueявляется путем , то было бы опасно использовать sedдля манипулирования им, поскольку технически оно может содержать символы новой строки. Использование расширения параметра в оболочке будет обрабатывать случай, когда путь содержит символы новой строки.

1
28.04.2021, 23:14

Теги

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