Когда вы выполняете
ls|more
оболочка анализирует эту строку и понимает, что три токена являются командой ls за которой следует конвейер, а затем команда more . Когда вы выполняете
$x
оболочка расширяет эту переменную, но не анализирует результат, по крайней мере, не так. Он разделит содержимое переменной на пробел, примет первую последовательность символов в качестве имени команды и следующие последовательности символов в качестве аргументов. Таким образом, она поймет, что ls|more будет командой ls|more и ls | more быть командой ls за которой следуют аргументы | и more , которое ls принимает за имена файлов.
Чтобы заставить оболочку анализировать содержимое этой переменной, используйте eval , например так:
eval "$x"