Perl批量POST设备信息脚本报错:500 Not a SCALAR reference
Hey there, let's tackle that frustrating "500 Not a SCALAR reference" error you're hitting with your Perl script. I've looked over your code, and the issue boils down to how you're passing the XML content to your HTTP request—you're using the XML::Twig object directly instead of converting it to a plain string first.
What's Causing the Error?
When you call $xml->sprint;, it generates the XML content as a string, but you're not saving that string to a variable. Then, when you pass $xml (the XML::Twig object itself) to HTTP::Request or $req->content(), the HTTP library doesn't know how to handle the object—it expects a scalar (plain string) for the request body. This mismatch is what's triggering the 500 error from the server.
Step-by-Step Fix
Here's how to adjust your script to fix the issue:
Capture the XML string output
Replace the standalone$xml->sprint;line with a variable that stores the generated XML string:my $xml_content = $xml->sprint;Use the scalar string for the request content
Update both places where you set the request content to use$xml_contentinstead of the$xmlobject:- Fix the
HTTP::Requestconstructor call - Remove the redundant
$req->content($xml);line (or replace it with$req->content($xml_content);if you keep it)
- Fix the
Fixed Full Script
Here's the corrected version of your script with the key changes highlighted:
use strict; use warnings; use XML::Twig; use LWP::UserAgent; use HTTP::Headers; use HTTP::Request; use File::Slurp; use LWP 5.64; use MIME::Base64; use IO::Socket::SSL; my $xml = XML::Twig -> new -> parsefile ( 'template.xml' ); $xml ->set_pretty_print('indented_a'); open ( my $input, '<', 'input.csv' ) or die $!; while ( <$input> ) { chomp; my ( $name, $ip ) = split /,/; # Optional: Handle possible whitespace in CSV entries # $name =~ s/^\s+|\s+$//g; # $ip =~ s/^\s+|\s+$//g; $xml -> root -> set_att('name', $name ); $xml -> get_xpath('//ipaddress',0) -> set_text($ip); # 1. Capture the XML string instead of discarding it my $xml_content = $xml->sprint; #Create a user agent object my $ua = LWP::UserAgent->new(ssl_opts=> { SSL_verify_mode => SSL_VERIFY_NONE(), verify_hostname => 0, } ); my $uri='https://hostname:9060/ers/config/networkdevice'; # 2. Pass the scalar string as the request body my $req = HTTP::Request->new( 'POST', $uri, [ Accept=>'application/vnd.com.cisco.ise.network.networkdevice.1.1+xml', Content_Type=>'application/vnd.com.cisco.ise.network.networkdevice.1.1+xml; charset=utf-8' ], $xml_content # Use the scalar string here ); $req->authorization_basic("user", "user"); #Pass request to the user agent and get a response back my $res = $ua->request($req); #Check the outcome of the response if ($res->is_success) { print $res->status_line, "\n"; # Optional: Print response content for debugging # print $res->content, "\n"; } else { print $res->status_line, "\n"; # Optional: Print error details from the server # print $res->content, "\n"; } }
Additional Tips
- CSV Whitespace Handling: If your Input.csv has spaces around commas (e.g.,
LAB-1, 10.26.0.1), uncomment the whitespace trimming lines to clean up$nameand$ip. - SSL Security: Disabling SSL verification (
SSL_VERIFY_NONE) is fine for testing, but in production, you should configureLWP::UserAgentto trust the server's valid certificate. - Debugging: If you still run into issues, uncomment the lines that print the response content—this will give you more context from the ISE server about what's wrong with the request.
内容的提问来源于stack exchange,提问作者StayCalm

