如何从Python向Shell脚本传递字符串列表并循环处理?
Let's fix this step by step. The error expected str, bytes, or os.PathLike object, not list happens because you're passing the entire list_1 as a single element in the subprocess.call argument list — subprocess requires all arguments to be strings, not nested lists. On top of that, we need to handle how the list gets passed through to the remote SSH session correctly.
Solution 1: Pass list elements as separate arguments (most reliable for special characters)
This approach treats each list item as a distinct command-line argument, which avoids issues with spaces or special characters in your fruit names.
Update your Python code:
Append each element of list_1 to the subprocess argument list directly:
import subprocess ssh_key_path = "#KEY_PATH" # Replace with your actual key path ip_address = "#BASTION_IP" # Replace with your actual bastion IP Details = "#Somedata" list_1 = ["apple", "banana", "carrot"] # Build the full argument list: fixed params + all list elements script_args = ["sh", "fruits.sh", ssh_key_path, ip_address, Details] + list_1 subprocess.call(script_args)
Update your fruits.sh script:
We'll first save the fixed parameters, then shift them out of the argument list so we can iterate over the remaining fruit items. We also need to make sure these values get passed correctly to the remote SSH session:
#!/bin/bash # Save the first three fixed parameters ssh_key="$1" bastion_ip="$2" details="$3" # Remove the first 3 parameters from the argument list shift 3 # Store the remaining arguments (our fruit list) in an array fruits=("$@") # SSH to the bastion and execute commands ssh -i "$ssh_key" ubuntu@"$bastion_ip" -o StrictHostKeyChecking=no << EOF printf "%s" "$details" > /home/Details.txt # Iterate over the fruit array for i in "\${fruits[@]}"; do echo "\$i" done echo "Success" EOF
Solution 2: Pass the list as a delimited string (good for simple elements)
If your list items don't contain special characters like spaces, you can join the list into a single string with a unique delimiter, then split it back into an array on the remote side.
Update your Python code:
Join the list with a delimiter (we'll use | here, pick something that won't appear in your items):
import subprocess ssh_key_path = "#KEY_PATH" ip_address = "#BASTION_IP" Details = "#Somedata" list_1 = ["apple", "banana", "carrot"] # Join list into a single delimited string fruits_str = "|".join(list_1) script_args = ["sh", "fruits.sh", ssh_key_path, ip_address, Details, fruits_str] subprocess.call(script_args)
Update your fruits.sh script:
Split the delimited string back into an array on the remote server:
#!/bin/bash ssh_key="$1" bastion_ip="$2" details="$3" fruits_str="$4" ssh -i "$ssh_key" ubuntu@"$bastion_ip" -o StrictHostKeyChecking=no << EOF printf "%s" "$details" > /home/Details.txt # Split the delimited string into an array IFS='|' read -ra fruits <<< "$fruits_str" for i in "\${fruits[@]}"; do echo "\$i" done echo "Success" EOF
Key Notes:
- Subprocess arguments must be strings: Never pass a list as an element in the
subprocess.callargument list — either expand the list into separate strings or join it into a single string. - SSH variable escaping: When using here-docs (
<< EOF), unquoted EOF lets the local shell replace variables before sending the command to the remote server, which is what we want here to pass our local script parameters to the remote session. - Special character safety: Solution 1 is better if your list items might have spaces, quotes, or other special characters, since each item is treated as a separate, properly escaped argument.
Either solution will produce your expected output:
apple banana carrot Success
内容的提问来源于stack exchange,提问作者Thra

