Как вам уже говорили (см. Почему не работает swappiness? ), изменение swappiness
влияет только на будущие решения, принимаемые ядром, когда ему нужно освободить память. Его уменьшение не приведет к тому, что ядро перезагрузит все, что было выгружено.
Ваш вывод vmstat
показывает, что подкачка активно не используется, т. е. ваши текущие рабочие нагрузки действительно не нуждаются в выгруженных страницах.
Нет смысла пытаться микро-управлять использованием подкачки ядром так, как это делаете вы. В зависимости от вашей рабочей нагрузки решите, нужно ли вам отдавать предпочтение кэшу страниц или нет, соответствующим образом настройте swappiness
, а затем оставьте систему работать.
Если вы действительно хотите очистить подкачку, отключите ее и -снова включите:
swapoff -a && swapon -a
Если вы хотите, чтобы вывод 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
лучше, так как эхо не работает с другими включенными строками. Это не происходит в этом случае, но это может быть в других.
Конвейер в том виде, в котором вы его построили, полагается на то, что выходные данные одной команды вводятся для другой. Вы пытаетесь запустить файл с именем my/value
и, по-видимому, получаете сообщение, что такого файла нет.
Есть несколько способов сделать то, что вы хотите.
Этот метод, по-прежнему использующий конвейер, вероятно, является наиболее переносимым.
operand="$(echo "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"
Если ваша оболочка поддерживает это, это альтернатива (должна работать как минимум в bash):
operand="$(sed -n -e 's/^\(.*\)\/.*/\1/p' <<< "$my_value")"
Последний метод несколько предпочтительнее, поскольку он не вызывает дополнительный процесс для отображения значения переменной.
В любом случае рекомендуется защищать содержимое переменных двойными кавычками.
Как указывали другие, вы пытаетесь выполнить значение $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
для манипулирования им, поскольку технически оно может содержать символы новой строки. Использование расширения параметра в оболочке будет обрабатывать случай, когда путь содержит символы новой строки.